home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kodak.com!news-nysernet-16.sprintlink.net!news-backup-east.sprintlink.net!news.sprintlink.net!128.122.253.90!newsfeed.nyu.edu!newshub.northeast.verio.net!news1.best.com!news3.best.com!nntp1.ba.best.com!not-for-mail
- From: pvdl@best.com (Peter van der Linden)
- Newsgroups: comp.lang.java.programmer,comp.lang.java.help,comp.lang.java.gui,comp.answers,news.answers
- Subject: Java Programmers FAQ
- Supersedes: <6vlf3m$r6n$1@shell15.ba.best.com>
- Followup-To: poster
- Date: 17 Oct 1998 16:54:10 -0700
- Approved: news-answers-request@MIT.EDU
- Message-ID: <70ban2$ak8$1@shell15.ba.best.com>
- Summary: This posting answers frequently-asked questions by Java programmers
- Lines: 8533
- NNTP-Posting-Host: shell15.ba.best.com
- X-Trace: 908668457 3286 pvdl 206.184.139.147
- Xref: senator-bedfellow.mit.edu comp.lang.java.programmer:162445 comp.lang.java.help:33873 comp.lang.java.gui:20675 comp.answers:33481 news.answers:142336
-
- Archive-name: computer-lang/java/programmers/faq
- Posting-Frequency: weekly
- Last-modified: 1998/10/17
- URL: http://www.afu.com/javafaq.html
-
- Frequently Asked Questions (with answers) for Java programmers
-
- _____________________________________________________
- ________| |________
- \ | Java Programmers FAQ http://www.afu.com | /
- \ | Last modified Oct 17, 1998 Peter van der Linden | /
- / |_____________________________________________________| \
- /___________) (__________\
-
- The Java FAQs here are intended for people who already have some programming
- experience, though maybe not in Java.
-
- Go to the FAQ home page at http://www.afu.com for other Java information and
- downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to
- faqidea at the address afu.com.
-
- ------------------------------------------------------------------------
-
- Specify standard Java on your new PC!
-
- Your new PC can come with the most up-to-date standard version of
- Java, but only if you ask for it! The JavaLobby is asking PC vendors
- to support Java, and to ship new machines with the Java Plug-In
- pre-installed.
-
- See http://www.javalobby.org/servlet/PetitionServlet/pjpc
- Please help the Java Lobby to promote this initiative.
-
- ------------------------------------------------------------------------
-
- Please support Java Portability.
-
- The biggest value of Java is its portability.
-
- * Portability makes it easier for companies to change/upgrade operating
- systems and platforms, without losing their investment in applications
- software.
- * Portability makes it easier for Java programmers to transfer their
- skills to new employers.
- * Portability makes a wider variety of software available on all
- computers.
-
- Software portability is very much in the interest of most software
- developers and customers. Even if you only use Windows 95, portability
- matters to you. If your software was all written in Java, it would all just
- run when you moved from MS-DOS to Windows 3.1 to Windows 95 to Windows 98 to
- Windows NT, and even on Windows CE. Instead, you typically need to buy new
- applications software all over again when Windows changes. Portability is
- not in Microsoft's interest, as it removes a revenue stream and makes it
- easy for users to try other operating systems.
-
- The 1998 anti-monopoly case against Microsoft revealed a Microsoft internal
- memo. The memo stated that Microsoft's strategic goal was to "kill
- cross-platform Java." If portability matters to you or your users, avoid
- Java products from Microsoft; it is deliberately undermining it. See
- http://www.usdoj.gov/atr/cases/f1700/1762.htm.
-
- -------------------------------
-
- The sections of the Java FAQ are:
-
- * Portability
- * 1. Java Book Information
- * 2. General Information
- * 3. Compilers and Tools
- * 4. Getting Started
- * 5. Compiler Messages
- * 6. Java Language issues
- * 7. I/O
- * 8. Core library issues
- * 9. Computer Dating
- * 10. AWT
- * 11. Swing
- * 12. Browsers
- * 13. Applets
- * 14. Multi-Media
- * 15. Networking
- * 16. Security
- * 17. For C, C++ Afficionados
- * 18. Java Idioms
- * 19. Java Gotcha's
- * 20. Further Resources
- * 21. Acknowledgements
-
- -------------------------------
-
- 1. Java Book Information
-
- 1. (sect. 1) Learning Java
-
- [*] The Java FAQ is maintained as a service to the Java community. Java
- is a great language, and everyone benefits when newcomers get a helping
- hand.
- Please consider these books from the FAQ author when you are looking
- for a programming text.
- o "Just Java 1.1" Java, for people who can already program in
- another language.
- More at http://www.amazon.com/exec/obidos/ISBN%3D0137841744
-
- Comments from a reader: "Just Java 1.1 is a great book! Before I
- bought it, I had a couple of other books that were OK, but I kept
- going back to the bookstore to check "Just Java 1.1" whenever some
- aspect of the language was unclear. Invariably the Just Java
- explanations were lucid and to the point. I just had to get it."
-
- o "Not Just Java" Java explained for managers and the rest of us.
- More info at http://www.amazon.com/exec/obidos/ISBN=0138646384
- Comment from readers: "...An excellent overview of the IT maze"
- "... Not Just Java lets readers educate themselves on where we
- are, and where we're going."
- "This book describes, with graphical illustrations, the emerging
- new ideas and how to use them."
-
- Sample chapters are on Sun Microsystems' webpage at
- http://www.sun.com/971124/cover-linden/.
-
- 2. (sect. 1) How do I choose a Java book?
-
- [*] There is no one right answer to "which is the right Java book for
- me?" It all depends on what you already know and how you like to learn.
- Here are the points to check when evaluating a programming book.
- o Above all, make sure that it is a Java book. If it comes with a
- CD, check that it has a Java compiler on it, not a J++ compiler.
- J++ is a different language in some small but important ways, and
- is missing several of the key Java libraries.
- If your interest is Java, leave the J++ book back on the shelf.
- o Check that the book has a reasonable number of figures, diagrams,
- and illustrations. It is not possible to explain how to program a
- window system without pictures and diagrams. Other topics benefit
- from pictures, too.
- o Check what the book says about itself. Is it a reference work,
- intended for Java-experts to look things up in? This is the role
- of "Java in a Nutshell", and "The Java Almanac". Do you need that,
- or are you looking for a book that teaches by examples and
- explanations?
- o Programming is one of those things that you learn by doing. Check
- that each chapter has exercises, preferably with answers. You'll
- need to do the exercises to learn the language.
- o Does the book cover the current level of Java, which is Java 1.1
- (with 1.2 in Beta). Look up "FileWriter" in the index. If it's not
- there, you probably want a more modern book. Look up "JApplet" in
- the index. If it's not there, the book doesn't cover JDK 1.2.
- o Appraise your own level of programming knowledge: are you
- proficient in some other language, or are you learning programming
- as well? Does the book cater to your needs?
- o Read a section of the book. Does the style keep you interested, as
- it educates you? Will you get bored if you read many pages? Is the
- book too long for your initial purpose? Browse Amazon online and
- see what other readers say about the text.
- o If the book comes with a CD, how much other software is on the CD?
- You want at least a Java compiler plus all the examples from the
- book. Does the Java compiler work on your platform (Mac, Linux,
- etc)? Additional software on the CD is a big plus, as we learn the
- most from reading other people's code.
- Probably no one book is perfect for anyone. Most people buy one to
- begin with, then four or five more as they wish to learn more, and
- about more up-to-date topics. The FAQ author has purchased and read
- probably 60 Java books in the last three years.
-
- 3. (sect. 1) Where can I find a some lists of Java books and book reviews?
-
- [*] Here are some good ones:
- http://www.flathill.com/languages/java/
- also
- http://teamjava.com/links/tj-srv.cgi?MUF=0,tj-booklist.muf
- also
- http://www.javaworld.com/javaworld/books/jw-books-index.html
- (an exhaustive list -- takes a long time to load).
-
- -------------------------------
-
- 2. General Information
-
- 1. (Sect. 2) Is Java "Open" or "Proprietary"?
-
- [*] The Java specification is publicly available, and anyone is free to
- do clean-room implementations of the JVM and core Java API's. Sun
- includes a perpetual, irrevocable, free and royalty-free license in the
- front of the Addison-Wesley books containing the specification.
-
- Sun also provides free access to the Java source. If you aren't
- planning on using the results in a commercial product, or doing any
- sort of external redistribution, there is an Internal Noncommercial Use
- Source License available at no charge. Please see
- http://java.sun.com/nav/business/source_form.html
-
- Using the Java trademark does requires licensing from Sun. It is not
- clear if the Embedded or Personal Java specifications are open, as it
- is not clear if a clean-room implementation may be done without
- licensing from Sun.
-
- The relative openness of Java contrasts with systems that are only
- available from one vendor, whose interfaces are developed in secret,
- without an open process for others to participate, whose owners do not
- allow competing implementations of the same API, and whose owners
- change the APIs as a strategic weapon against competitors. Typically,
- such systems also feature "private" APIs that are published late or not
- published at all, to allow the single vendor to gain a competitive
- advantage for their other products. Typically such proprietary systems
- do not make the source code available for inspection by all.
-
- 2. (Sect. 2) What is the best way to refer someone to the FAQ when they
- ask a question I know is answered there?
-
- [*] The Java Programmers FAQ (at http://www.afu.com) answers your
- question in section N.n. ...
-
- This gives them the answer, and shows them where to go for future
- questions. It also demonstrates that the FAQ can answer their
- questions, supplying an incentive to go there next time. It's regarded
- as elementary politeness to look for the FAQ of a newsgroup and read it
- before posting any questions.
-
- In general, FAQs for any newsgroup are available by looking at past
- postings in a group, or by searching Deja News (see Q 1.4), or via
- anonymous FTP at directories under ftp://rtfm.mit.edu. The pathnames
- are called things like
- /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ
- which may help you get to the right one directly, as it takes some time
- to get a directory listing there. Alternatively, you can look for
- newsgroup names on the same ftp site by going to the same site and
- looking under /pub/usenet-by-hierarchy/. That has subdirectories such
- as alt/, ba/, ca/, comp/, and subdirectories under them such as
- /pub/usenet-by-hierarchy/comp/lang/ and so on. This helps you explore
- the world of newsgroups with FAQs.
-
- If you do not have anonymous FTP access, you can access the
- rtfm.mit.edu archives by mail server as well. Send an E-mail message to
- mail-server@rtfm.mit.edu with "help" in the body for more information.
- "RTFM" stands for "Read The effing Manual" - you must expect to put in
- some time and effort to master a new area of study.
-
- If you want to look at the definition of Internet standards like FTP,
- telnet, visit the IETF site at http://www.ietf.org where all the RFC's
- (Request For Comments) can be found.
-
- 3. (Sect. 2) What if my question is not answered in this FAQ?
-
- [*] Go to http://www.dejanews.com/home_ps.shtml
- o Under "Newsgroups" enter "comp.lang.java.programmer" (or whatever)
- o Under "Subject" enter "Frotteur" (or other topic you find
- pressing)
- o Click "Create Filter"
- o It will go to a new document, and you should click the link
- labeled
-
- nnn Documents (nnn is some number).
-
- The chances are that you will find several answers to your question.
- Some may not be complete or completely accurate however. That is the
- nature of Usenet, and free information. If you still don't have an
- answer, then post your question on the most appropriate of the
- newsgroups. Don't spam the newsgroups by posting to multiple groups.
- Knowledgeable posters tend to ignore questions like that.
-
- Also look at http://sunsite.unc.edu/java/cgi-bin/query
- and look at http://asknpac.npac.syr.edu/ for a Java newsgroup search.
-
- http://www.javaworld.com/search.html can search the Javaworld
- newspaper.
-
- 4. (Sect. 2) What Java mailing lists are there?
-
- [*] There are quite a few Java mailing lists.
- http://java.miningco.com/msub7.htm has a comprehensive list.
-
- 5. (Sect. 2) Where can I look at the definitive Java Language
- Specification?
-
- [*] This is available online at:
- http://java.sun.com/docs/books/jls/html/index.html (Java 1.0)
-
- and the Java 1.1 inner classes document at:
- http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/
- spec/innerclasses.doc.html
-
- and the other Java 1.1 update at:
- http://java.sun.com/docs/books/jls/html/1.1Update.html
-
- and the Java API is at:
- http://java.sun.com/products/jdk/1.1/docs/api
-
- It is also available as a book in printed form (details at website).
- Also see the "Clarifications and Amendments"
- http://java.sun.com/docs/books/jls/clarify.html.
-
- You can also see the virtual machine (execution environment)
- specification at
- http://docs.sun.com:80/ab2/java1/@Ab2CollToc?subject=java
-
- 6. (Sect. 2) Where can I find information about future Java APIs?
-
- [*] JavaSoft has followed a policy of creating new APIs in consultation
- with leading industry participants, then posting the draft
- specification for public review and comments. Check the JavaSoft
- roadmap of new APIs and products at
- http://java.sun.com:80/products/api-overview/index.html
- Also, some APIs that are under consideration, possibly for JDK 1.2 are
- at:
- http://java.sun.com/products/jdk/preview/docs/
-
- 7. (Sect. 2) I'm looking for a Java style guide on naming conventions.
-
- [*] Check out the section "Naming Conventions" in the language
- specification
- http://java.sun.com/docs/books/jls/html/6.doc.html#11186
-
- Also take a look at Doug Lea's draft coding standard -
- http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
-
- See also naming conventions for some basic rules of thumb.
-
- 8. (Sect. 2) How do I check on known bugs in the JDK?
-
- [*] Look at the Java Developer Connection at http://java.sun.com/jdc.
-
- All the Java bugs that Sun knows about are listed there, with the
- exception of security-related bugs. The legal department in Sun vetoed
- the open publication of security bugs. After you have checked that the
- bug is not already listed, you can submit a bug report through:
- http://java.sun.com:80/cgi-bin/bugreport.cgi
- You should check that the bug doesn't already exist for two reasons:
- first, you might find the bug with a workaround listed. Second, you
- don't want to waste everyone's time with a duplicate bug report.
-
- You can also send in an RFE (Request For Enhancement) or ease-of-use
- issue there. You can even vote on the priority you would assign to a
- particular bug fix! Join the Java Developer Connection (it's free) by
- going to http://java.sun.com/jdc. Then browse
- http://developer.javasoft.com/developer/bugParade/#votes
-
- 9. (Sect. 2) What computers have Java ports? Is there a port to Win 3.1?
-
- [*] A partial list of JDK ports is available from
- http://java.sun.com/cgi-bin/java-ports.cgi
- An (impressive) list of the systems that the GPL Kaffee JVM runs on is
- at http://www.transvirtual.com/ports.html
-
- There are several Java ports to Win 3.1. IBM's ADK1.02 is available at
- the following locations:
- o http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html
- o http://www.alphaworks.ibm.com/formula
- IBM offers a port to Linux, as do others. The IBM Jikes port is at
- http://www.alphaworks.ibm.com/ There is a large amount of useful
- software there, including a profiling tool called jinsight (caveat: it
- may not work with all releases of JDK 1.1, i.e. not JDK 1.1.6).
-
- Netscape Navigator for Win3.1 has Java support. Java will never be
- well-supported under Win3.1 because Win3.1 lacks the basic features
- expected of a modern OS (primarily lengthy filenames and multithreading
- support).
-
- Also take a look at JavaSoft's JavaPC kit that can switch a PC into a
- thin client Java system (and back to Win3.1/DOS when you want). It's
- meant for software OEMs and large corporations running lots of older
- PCs, but you can use it on the latest Pentium II too. Details are at
- http://java.sun.com/products/javapc/index.html. JavaPC is available now
- for $100, runs on 486's with 8Mb or more Unlike the 16-bit versions of
- Netscape Navigator and Microsoft Internet Explorer, which provide a
- Java Virtual Machine that is only compliant with the JDK 1.0.2 API, the
- JavaPC software allows IS managers to deploy JDK 1.1-compatible Java
- applications on PCs running DOS and Windows 3.x.
-
- 10. (Sect. 2) Where can I find information on Java 3D?
-
- [*] The Java 3D FAQ at http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html
- may have the answers you're looking for. It contains general
- information about Java 3D, as well as programming tips.
-
- 11. (Sect. 2) Where can I find information about Java Certification?
-
- [*] Sun is sponsoring an examination which programmers worldwide can
- take. Those passing can use the designation "Sun Certified Java
- Programmer". There is also a second-level test, involving writing a
- program to spec, and taking a further test. That results in the
- qualification "Sun Certified Java Developer". You can find out all
- about the exam at:
- http://www.sun.com/service/suned/
-
- and then search for "sun certified java". It costs $150 to sit the Java
- Programmer exam. It is not trivial to pass the Java certification exam.
- It requires understanding the objectives of the test, and the material
- that is tested for. These are given, along with sample questions, at
- the URL mentioned above.
-
- 12. (Sect. 2) How can I find links to recent news about Java?
-
- [*] This site contains links to late-breaking online news stories about
- Java. http://www.intelligence.com/java/
- Another good Java news source is http://www.nikos.com/javatoys.
-
- This site is a fine site for programmers who want to be well-informed
- about computer industry topics. It has a lot of coverage of Linux as
- well as more general news. http://slashdot.org Highly recommended.
-
- This site is a source of independent news and commentary on the
- computer industry, including Java. http://www.pjprimer.com/media.html.
- You have to subscribe ($10/year, 30 day free trial).
-
- 13. (Sect. 2) What are the folks at GNU doing with Java?
-
- [*] First note that the URLs in this section change quickly, and soon
- become outdated. If you have an update, send it in. There is a Gnu Java
- page at http://www.gnu.org/software/java/java.html
- Guava (a GPL'd Java compiler) can be found at
- ftp://ftp.yggdrasil.com/pub/dist/devel/compilers/guavac/
- Alternatively, it may be available at
- http://http.cs.berkeley.edu/~engberg/guavac
- Work is progressing on the Cygnus Java frontend to gcc. See
- http://www.cygnus.com/product/javalang/
-
- Kaffe (a JVM) can be found at
- http://www.transvirtual.com This is Tim Wilkenson's company
- devoted to commercializing the Kaffe JVM for the embedded systems
- market. He also releases a version of it under the GPL. It also
- comes with a the beginnings of a class library and the Pizza
- compiler.
-
- Classpath is a free implementation of Sun's core Java libraries (v1.1),
- being developed for the GNU Project ( http://www.gnu.org). Information
- regarding classpath is at http://www.classpath.org They aim to develop
- a 100% free drop in replacement for Sun's class libraries, targeting
- first the Japhar JVM (below). They are always looking for help, so feel
- free to stop by and volunteer.
-
- See also http://www.japhar.org This is the Hungry Programmer's JVM.
- Currently it is development grade only.
-
- 14. (Sect. 2) What is "San Francisco"?
-
- [*] San Francisco is the code name for a very large Java project led by
- IBM, and involving other companies. The project is to provide a Java
- framework for data processing applications. A large number of classes
- are provided for general ledger, sales order, inventory management,
- etc., and these classes can be extended and customized for particular
- industries (vertical markets). It is a large and ambitious software
- project.
-
- IBM's SF project competes with products from companies like SAP and
- Baan. Of course, the SF project is multi-platform and uses Java beans
- and GUI interfaces. More information on SF is available at
- http://www.ibm.com/Java/Sanfrancisco
-
- 15. (Sect. 2) What large Office-style or other applications have been
- written in Java?
-
- [*] Well, the first one to consider is IBM's San Francisco project,
- mentioned above. There is also Lotus's e-suite - a suite of Java
- applets and beans including a spreadsheet and a word processor. See
- http://esuite.lotus.com. These became available in March 1998.
-
- Another office suite in Java is Applix Anyware at
- http://www.applix.com/anyware/index.htm. Applix became available in
- downloadable demo form in April 1998.
-
- Yet another is Star Division's Client/Server Office. It is an office
- suite with the client part written in Java and able to run on
- JavaStations. The server part will run on Solaris, NT, OS/390, and
- AS/400. The older (non-Java) version is bundled with all Sun
- workstations sold in Germany. The Linux version is freely downloadable
- from http://www.stardivision.com.
-
- Another is Digital Harbor's Wav word processor. It supports component
- software, and it runs in 1MB, not the 114Mb of the latest MS Word. A
- free trial is avilable. See: http://www.digitalharbor.com
-
- Another Java application is Formula One for Java, an Excel-compatible
- spreadsheet written in 100% pure Java, and available for all systems
- that support Java. It runs as a Java Bean, so can easily be assembled
- as one component of a larger system. Formula One is a product of Visual
- Components, Inc. See http://www.f1j.com.
-
- Another one is Ncode Research Inc. who write Java viewers for office
- suites. They are file-format specialists. Their mission is to make all
- popular file formats available for the Java platform. They write 100%
- Pure Java viewers for Word, Excel and PowerPoint (including Office 95
- and 97 formats). See http://www.ncode.com/
- Another company operating in the same space is JSoft, at
- http://www.jsoftinc.com
-
- The niche for single-user office productivity applications is pretty
- well already dominated by Microsoft products, and it is unrealistic to
- think that Java software will unseat shrink-wrapped software simply
- because it is written in Java. This is why Corel replanned its Java
- rewrite of Corel Office before taking it to FCS. When Corel did that,
- it also increased its investment in Java from 33% of R&D budget to 50%,
- at the expense of Windows.
-
- Most of Java development is taking place for custom applications
- internal to a company. Most programmers of any kind have never worked
- on MS Office, but work on internal applications, and so it is with
- Java. These projects don't have the high profile of major vendors'
- products, but they are the mainstay of the industry. There are many
- companies working on Java Beans, like http://www.quadbase.com who have
- Java graphing software. EspressChart is a Java Bean that gives you the
- ability to add 2D and 3D graphs in your applications/applets. This bean
- is easy to use, 100% Java, and runs anywhere.
-
- There are some good Java games applets at
- http://www.frontiernet.net/~imaging/java_games.html
- If you want to use Java to learn math & computer graphics, visit
- http://www.frontiernet.net/~imaging/math_is_a_game.html
-
- Finally, note that Sun's Java compiler is written in Java. This is a
- really big application in widespread use on millions of platforms. The
- compile command "javac test.java" is equivalent to
-
- java sun.tools.javac.Main test.java
-
-
- javac has a script wrapper just to set the heap size as a command line
- argument, as you can do in your own programs.
-
- 16. (Sect 2.) What Java User Groups are there?
-
- [*] There are scores of Java User groups around the world, mostly in
- urban areas, and centers of software technology development. A partial
- list with contact information can be found at
- http://sunsite.unc.edu/javafaq/usergroups.html.
-
- If you can't find a user group in your area/school, it's easy and
- satisfying to start one.
-
- 17. (Sect 2.) What is a Java Bean?
-
- [*] A Java bean is a Java class that follows some simple conventions.
- Because it follows conventions, it can easily be processed by a
- software tool that connects Beans together. Java beans are reusable
- software components.
-
- Think of Java beans as being the software equivalent of Lego[tm]
- bricks. Instead of plugging together plastic bricks, you can easily
- plug together classes, and have them fit and work with each other. See
- http://www.jc100.org/
- See the Java Bean FAQ at http://java.sun.com/beans/faq/faq.general.html
-
- 18. (Sect 2.) Where can I find examples of the use of the Java class
- libraries?
-
- [*] The two volumes of "Java Class Libraries" by Chan, Lee and Krama
- published by Addison Wesley, have extensive examples of how to use the
- standard libraries. One programmer comments "When I need to use an
- unfamiliar area of the class libraries one of the first things I do is
- read their examples." You can see them online at
- http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html
- and http://java.sun.com/docs/books/chanlee/second_edition/examples.html
-
- -------------------------------
-
- 3. Compilers and Tools
-
- 1. (Sect. 3) Is there a lex and yacc or preferably a flex and bison
- equivalent for Java?
-
- [*] There is a lex equivalent called JavaLex and a yacc equivalent
- called CUP.
-
- LALR(1) parser JavaLex and JavaCup:
- http://www.cs.princeton.edu/~appel/modern/java/
-
- LL(k) parser JavaCC: http://www.suntest.com/JavaCC/
- LALR(1) parser SableCC from McGill U.
- http://www.sable.mcgill.ca/sablecc/index.html is generously made
- available under GNU license.
-
- 2. (Sect. 3) Where can I find a byte code obfuscator?
-
- [*] There is a commercially supported obfuscator, with a downloadable
- free trial at http://www.4thpass.com/SourceGuard. There are also some
- free works from students and others. http://www.primenet.com/~ej/
- http://www.math.gatech.edu/~mladue/HoseMocha.java
-
- Some people have reported problems using these with JDK 1.1.
-
- This obfuscator has been updated to be fully compatible with JDK 1.1:
- http://www.monmouth.com/~neil/Obfuscate.html
-
- Obfuscators are intended to foil decompilers. Decompilers translate
- byte code back into Java source code. Mocha was the first and most well
- known of the decompilers; it's no longer supported. There is a
- decompiler (written in C++) at
- http://web.unicom.com.cy/~kpd/jad.html
- Because it is in C++, there are different versions for every
- architecture (hah!) There are also commercial products, such as
- SourceAgain from
- http://www.ahpah.com/
-
- There's a very good Java Code Engineering and Reverse Engineering FAQ
- page at http://Meurrens.ML.org/ip-Links/Java/codeEngineering/.
-
- 3. (Sect. 3) Which program is used to create .zip files compatible with
- the java* programs?
- (e.g. classes.zip, moz3_0.zip)
-
- [*] Use the jar-tool from JDK1.1(.1):
- jar [ options ] [manifest] destination input-file [input-files]
-
- E.g.:
- jar cvf myJarFile.jar *.class
-
- creates a compressed archive
- jar cvfO myJarFile.zip *.class
-
- creates it fullsize (uncompressed) (note the 'O'-option used for
- JDK1.0.2)
-
- On Unix you can also use:
- zip -rn ".class" my_file.zip *
-
- Info-ZIP home page: http://www.cdrom.com/pub/infozip/
- Latest source code: ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip
-
- Netscape's command line version of its JAR packager and signing tool is
- called "zigbert". They also have a signing tool with GUI written in
- Java. More info
- http://developer.netscape.com/software/signedobj/jarpack.html
-
- If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar):
- 1. zip your files uncompressed (can use WinZip 6.2 up);
- Unix command:
-
- zip -r0 classes.zip <directories>
-
- 2. Make sure the main class has no parent directory inside the
- archive, (in other words, don't build an archive with
- foo/bar/myMain.class, unless your myMain is in a package called
- foo.bar. Instead start it at myMain.class). Your packages must be
- placed in the archive using their corresponding filesystem
- pathnames.
- 3. Put the archive in the same directory as the .html page.
- 4. Put something like the following tag in the .html file:
-
- <APPLET CODEBASE="."
- ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip
- CODE="my_main_class.class"
- WIDTH=600 HEIGHT=250>
- </APPLET>
-
-
- From JDK 1.1 on, an example of the applet tag used with a jar file is
-
- <APPLET ARCHIVE=myfile.jar
- CODE=myapplet.class
- WIDTH=600 HEIGHT=250>
- </APPLET>
-
-
- These lines will use an applet called myapplet that can be found in the
- jarfile myfile.jar. An example applet tag of a jar file used to hold
- classes in packages is
-
- <APPLET ARCHIVE="myclasses.jar"
- CODE="linden.net.MyApplet.class"
- WIDTH=480
- HEIGHT=120>
- </APPLET>
-
-
- You can supply several jar filenames in a comma-separated list. Jar
- files are in compressed PKZIP format.
-
- 4. (Sect. 3) Can I compile a Java program to a binary executable, .exe on
- a PC?
-
- [*] Compiling into native code destroys portability, which is one of
- the main benefits of Java. If you want to create a native executable
- because you wanted to make it easy to distribute and use programs,
- consider a Jar file instead.
- Some companies make products that do this. See the webpages for
- Symantec http://www.symantec.com, Supercede http://www.supercede.com,
- and Tower Technology http://www.twr.com. The first two are targeted to
- Windows. Tower Technology supports several flavors of Unix.
-
- Also, there is a native Java compiler from IBM, known as the HPJ (High
- Performance Java) compiler. One user has reported that it created a 2Mb
- executable from a 12K java file, and did not run any faster. See
- http://www.alphaworks.ibm.com/
-
- See also Instantiations JOVE http://www.instantiations.com/jove.htm,
- the paper about the Toba project
- http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf,
- Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at
- http://www.nwfusion.com/news/0209java.html
-
- Compiling to native code takes away the most significant benefit of
- Java: portability of executables. Further, if you want your Java DLL
- (or .exe) to interact with C++, you'll have to specify which specific
- C++ compiler and/or actually compile some sort of linkage via the
- appropriate C++ compiler. Because C++ does not have a standard ABI
- there is a big problem with interoperability. Every C++ compiler uses a
- different object model, a different way of laying out class members,
- and a different way of "mangling" names for the linker.
-
- C is much simpler. The only question here is how structures are
- "packed" (i.e., are integers aligned on four-byte bounds?). All the C++
- compilers can interact with C code, thanks to 'extern "C"'
- declarations.
-
- Consider carefully why you want to compile to a native executable, and
- whether there is a Java way to accomplish your goal. There may be a
- good reason for compiling to native code, but it needs to be thought
- through.
-
- 5. (Sect. 3) How can I performance profile my Java code?
-
- [*]java -prof MyClass
-
- produces some basic output in a file called java.prof, showing the
- number of times methods were invoked. The output lines are of the form:
- # of calls method called called by time spent
- On a Unix system, you can sort the file with something like
-
- sort -r +82 <java.prof > java.sort
-
- More and better Java tools are a third party opportunity. One Java
- profiler is JProbe Profiler, available from http://www.klg.com/jprobe.
- JProbe is said to be easy to use. Another profiler is OptimizeIt,
- available from http://www.optimizeit.com. Each of these profilers has
- performance tuning, which shows which methods took how much time, and
- also memory tuning, which shows what objects are in memory and how they
- were allocated. Both are important things to know. The latest version
- of the CodeWarrior IDE http://www.metrowerks.com has a time-based
- profiler for Java code. Java Workshop from Sun also has a time-based
- profiler.
-
- 6. (Sect. 3) When I use javadoc and I click on any java class included in
- the JDK why do I get this message?
-
- Netscape is unable to find the file or directory named:
- /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html
-
-
- [*] References to the JDK classes assume that all generated html files
- are in the same directory and, in fact, that all files for all classes
- referenced are generated at the same time. There is no way to generate
- files incrementally and have them all reference each other, as you
- would like.
-
- As long as you have source for everything involved (including the JDK
- and all third-party classes), you can list all of your packages and all
- of the others on the javadoc command line and generate the whole set at
- once, but it is burdensome. Of course, if you receive any libraries as
- .class files, even this workaround will not suffice.
-
- Also javadoc will not generate the image files - you need to get them
- from the images directory under the JDK API documentation files. You
- can just copy the entire directory into your own doc directory. javadoc
- is a very nice concept, with a few implementation flaws.
-
- Polardoc http://www.ualberta.ca/~tgee/polardoc can be used to
- workaround some JavaDoc limitations.
-
- 7. (Sect. 3) I'm working on a project with lots of classes and I use the
- JDK. A recompile from scratch takes forever when I do it a class at a
- time. How do I recompile everything?
-
- [*] The first way is
- javac *.java
-
- Another way is
- javac -depend tip.java
-
- where "tip.java" is a class "at the tip of the iceberg", i.e. that
- depends on (uses) all the other classes. Typically, this may be your
- main class. However, "-depend" is known to be buggy and cannot be
- relied upon. It also doesn't issue compile commands in parallel to make
- use of multi-processor systems.
-
- Without the "-depend" option, the standard "javac files" doesn't look
- beyond the immediately adjacent dependencies to find classes lower down
- the hierarchy where the source has changed.
-
- The -depend options searches recursively for depending classes and
- recompiles it. This option doesn't help when you have dynamically
- loaded classes whose names cannot be determined by the compiler from
- the dependency graph. E.g. you use something like
- Class.forName(argv[0]);
-
- The author of the code using those classes should make sure that those
- classes are mentioned in a Makefile.
-
- 8. (Sect. 3) Why do I get the java.lang.UnsatisfiedLinkError when I run my
- Java program containing Native Method invocations?
-
- [*] Your program is not able to find your shared library or DLL.
-
- On Windows 95/NT, make sure that the DLL exists in a path that is
- included within the PATH environment variable. (This need is true for
- both standard (untrusted) applications and trusted applets. At least,
- if you use the Java Plug-in to give yourself standard Java inside a
- browser).
-
- On Solaris, make sure that the environment variable LD_LIBRARY_PATH
- includes the path of your shared library.
-
- 9. (Sect. 3) An anonymous class can't seem to access a private outer
- method. Why is that?
-
- [*] It's a known bug in the JDK 1.1.4. The code is:
-
- public class MyDialog {
-
- void Setup() {
- addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- myCloseWindow(); }
- }
- ); // anon inner class
- }
-
- private void myCloseWindow() { // private outer method
- dispose();
- }
- }
-
- This code sends javac into an infinite loop. The workaround is to make
- the private method non-private, or to make the inner class a named
- class. Sun put a workaround in the compiler to silently set the field
- to package access.
-
- 10. (Sect. 3) What are the major Java releases and their contents?
-
- [*] There have been three Java releases from Sun so far, plus a number
- of bugfix (dot-dot) releases. The releases are:
- o JDK 1.0.2
- This was the release FCS in May 1996. It had some security fixes
- over JDK 1.0.
- o JDK 1.1
- This release (Feb 1997) introduced a new event model in the window
- system. It also made JDBC support and beans support a standard
- feature. It changed and standardized the native code interface to
- JNI. It also introduced inner classes.
- o JDK 1.2
- This release (due November 1998) made the Swing library a standard
- feature. Swing is a set of rich platform-independent graphical
- components.
-
- 11. (Sect. 3) What is the difference between jre and java?
-
- [*] They are functionally equivalent, with minor differences in the
- handling of default classpath and options supported. To reduce
- confusion, the jre command will go away in JDK 1.2. (Instead there will
- be a "java" command in both bin and jre/bin. The classes.zip file will
- broken into 3 jar files: It changed and standardized the native code
- interface to JNI. It also
-
- jre.exe is the runtime stub that comes with the Java Runtime
- Environment (it's also in the JDK). It ignores the CLASSPATH
- environment setting in favor of its own internally generated default
- and whatever is supplied on the cmd line using -cp or -classpath. It's
- intended to be a bit simpler for those who are only ever running Java
- programs, not developing them.
-
- java.exe is the runtime stub that only comes with the JDK. It uses the
- CLASSPATH environment setting as a starting point and then tacks on its
- own internally generated entries.
-
- They both serve the same purpose and that's to start a Java VM, have it
- run a Java application, then terminate. The source for jre.exe is
- provided in the JDK. The source to java.exe is provided only in the JDK
- Source distribution.
-
- 12. (Sect. 3) What IDEs (Integrated Development Environments) are there?
-
- [*] Some popular IDEs include:
-
- Apptivity 2.0 (Progress) http://www.apptivity.com
- CodeWarrior Professional http://www.metrowerks.com
- GRASP (product is free) http://www.eng.auburn.edu/grasp
- Grinder http://www.tpex.com
- Java WorkShop 2.0 (Sun) http://www.sun.com/workshop/java
- Javelin, Visual Object
- Development for Java http://www.stepahead.com.au
- JBuilder (Borland) http://www.borland.com/jbuilder
- JDE for emacs http://sunsite.auc.dk/jde/
- Kawa (Webcetera) http://www.tek-tools.com/kawa
- NetBeans (Swing-based) http://www.netbeans.com
- PARTS alpha (ObjectShare)http://www.objectshare.com
- PowerJ ? (Sybase) http://www.sybase.com/products/powerj
- SilverStream http://www.silverstream.com
- Super Mojo (Penumbra) http://www.penumbrasoftware.com
- SuperCede 2.0 (Asymetrix)http://www.supercede.com
- teikade 1.8R2 (PFU Ltd) http://www.pfu.co.jp/teikade
- Together/J 2.0 (Object
- Intl Inc.) http://www.oi.com
- Visaj 1.0.1 (Imperial SW
- Tech) http://www.imperial-software-tech.co.uk
- VisualAge 1.0 (IBM) http://www.software.ibm.com/ad/vajava
- Visual Cafe 2.1
- (Symantec) http://cafe.symantec.com
- Visual J++ (Microsoft) (deliberately incompatible; not recommended)
- Xelfi 0.94 http://www.xelfi.com
-
- 13. (Sect. 3) Why is Visual J++ not recommended?
-
- Because Microsoft's strategic objective is "Kill cross-platform Java"
-
- [*] It is not in Microsoft's financial interest to allow users to
- easily move software to different platforms. Microsoft is the only
- company in the computer industry that is actively trying to undermine
- Java. This is not speculation -- the Department of Justice's lawsuit
- quoted a Microsoft memo describing the strategic objective to "kill
- cross-platform Java by grow[ing] the polluted Java market". See
- http://www.usdoj.gov/atr/cases/f1700/1762.htm
-
- Microsoft is being sued because of unauthorized changes it made in
- Java. A federal judge issued a preliminary injunction against Microsoft
- in March 1998, prohibiting them from labelling their incompatible J++
- product as Java.
-
- Speak to your management
- chain - how comfortable do
- they feel using a Microsoft product that is embroiled in a legal
- dispute, that introduces deliberate incompatibilities, and whose stated
- goal is to lock you in to one platform? It is a safer choice to get
- standard Java from any other source than Microsoft. You can use these
- facts to move your company to standard Java.
-
- The best way for programmers to support portable Java is to reject
- "polluted" non-standard tools from the only company pushing them:
- Microsoft. As a Java programmer please join the Java Lobby, an
- independent organization dedicated to representing non-vendor interests
- in Java. It's free, and you can sign up by visiting
- http://www.javalobby.org for details. Other ways to encourage portable
- java:
- o Use development environments from other vendors, or convert
- Microsoft Visual J++ to use Sun's JDK, following the instructions
- at http://www.orbiter.demon.co.uk/
- o Use Netscape Communicator (not Internet Explorer)
- o If required to use Internet Explorer, use the Java Plug-In to get
- a standard Java system inside it.
- o Use a JVM from GNU, Kaffe, or Sun (not Microsoft's J++ SDK)
-
- o Free standard Java compilers and the Java Plug-In can be
- downloaded from http://java.sun.com.
- o Free standard Java Virtual Machines can be downloaded from
- http://www.kaffe.org, http://www.oryxsoft.com/projects/gvm, and
- http://www.redhat.com/linux-info/jolt
- o Free Java AWT software can be downloaded from
- http://www.biss-net.com/biss-awt.html and the files are all at
- ftp.java-linux.org (the linux site) too.
- o Free Java software can be downloaded from
- http://www.gnu.org/software/java/java.html
-
- Just for the record, the May 1998 federal case against Microsoft has
- nothing to do with innovation, or product design. Microsoft is charged
- with
- o taking anti-competitive action to exclude competition in browsers,
- in order to protect its monopoly in desktop operating systems.
- o using its monopoly to impose restrictive agreements that require
- PC manufacturers to accept the Microsoft browser with Windows, and
- that hinder the promotion of competing browsers.
- Many people think that contracts prohibiting the distribution of a
- third party's products are somewhat sleazy. Such contracts are also in
- restraint of competition and illegal when used by a monopoly. This is
- why Microsoft is facing mounting legal problems in the United States,
- Japan, Brazil, and the European Union.
-
- -------------------------------
-
- 4. Getting Started
-
- Don't forget to look at the "Compiler Messages" in the next section,
- too.
-
- 1. (Sect. 4) What is the easiest way to get started with Java?
-
- [*] Follow these steps.
- 1. Download a free Java compiler from http://java.sun.com
- 2. Read the free Java tutorial, at the same website (bookmark it, so
- you will easily find it again).
- 3. Avoid Microsoft's J++ product, which is in the words of
- Microsoft's own employees "polluted Java".
- 4. Look at the beginning of this FAQ for book info and book reviews.
- There is no one perfect Java book. The right book depends on the
- style and pace that you are most comfortable with. Amazon.com has
- good info and reviews on Java books.
- 5. Search this FAQ when something in Java confuses you. Many people
- have trodden this path before you, and the FAQ contains the
- accumulated knowledge and pointers to other references.
- 2. (Sect. 4) Why doesn't my "Hello World!" program compile?
-
- [*] There are three basic possibilities:
- 1. Are you successfully running the javac compiler?
- Try
-
- javac -garbage
-
- to see if it prints out a message about correct usage. If not,
- invoke javac using the full pathname, or set your PATH variable to
- include the directory that contains javac.
- 2. Is the CLASSPATH environment variable used correctly?
- In JDK 1.0.2, it was a mistake for beginners not to set CLASSPATH.
-
- In JDK 1.1, it is a mistake when beginners do set CLASSPATH.
- When CLASSPATH is wrong, javac will tell you it can't find
- definitions for classes you reference in the source file. For
- information on setting up the CLASSPATH, see Question 4.3
- 3. Is the source correct?
- Here javac will emit error and warning messages. See the questions
- on compiler messages in the next section.
-
- 3. (Sect. 4) Why doesn't my "Hello World!" program run?
-
- [*] There are five common mistakes that cause your VM (java or browser)
- to be unable to execute your classes
- 1. First, did you write an applet or an application? If an applet,
- you must make sure that you did extend the java.applet.Applet
- class.
- 2. You must declare your main class as "public". If you don't,
- unfortunately some systems will still run the code, while others
- won't. The main class is either the one with the main() method in,
- or in the case of an Applet, the class that extends Applet.
- 3. Your class name and the file name must match exactly, even letter
- case. If your class is HelloWorld, your source file must be
- HelloWorld.java and your class file will be "HelloWorld.class".
- 4. If an Applet, and you used ftp to transfer the classes to the
- server, you must ftp all the classes, and you must use BINARY
- transfer not ASCII.
- 5. Errors in setting the CLASSPATH (and/or codebase in an applet).
- Even seasoned programmers do this, pointing inside a package or
- mistyping a path delimiter. For information on setting up the
- CLASSPATH and codebase, see Question 4.3
-
- If you are running an applet, you should check the following further
- points:
- 1. If your class isn't loading, recheck the HTML applet tag.
- 2. If you are writing to System.out, the results are displayed in the
- browser's java console. You'll have to create a window if you want
- one.
- 3. Make sure your browser is compatible with the Java language
- features you are using. Internet Explorer and older versions of
- Netscape's browsers have omitted some support for JDK 1.1. Try
- your applet in the JDK's appletviewer first.
-
- 4. How do I set the CLASSPATH?
-
- [*] The CLASSPATH environment variable tells the VM's class loader
- where to find classes that are directly or indirectly invoked,
- including system classes. The CLASSPATH variable should
- o point to the class directory, for classes not in a package.
- o point to the package root, for classes in a package. The root is
- the parent directory of the highest directory of the package name.
- o point directly to the zip or jar file, if the classes are in an
- archive file. You may have to list the contents of the archive to
- get the correct package/path name for the class.
- Separate multiple paths and archives with a platform-specific
- separator, ";" for Windows; ":" for Solaris
- Also remember that
- o Browsers set the CLASSPATH to the directory of the HTML file, plus
- the codebase parameter.
- o in JDK 1.1 and after, java adds the system classes
- (lib/classes.zip), so you don't have to.
- o most versions of java add "." (current directory), so you don't
- have to. (But jre doesn't - see below.)
- o JDK 1.1 jre tool does not use the CLASSPATH variable or assume the
- current directory. (On Solaris, CLASSPATH does work.)
-
- From JDK 1.1.2 on, it is generally an error if the user sets the
- CLASSPATH to include classes.zip. But CLASSPATH will need to be set to
- o point to the roots of the programmer's own packages, and third
- party packages
- o use rmic
- o use unbundled packages like Swing in JDK 1.1
- o point to native code libraries.
-
- If you're not doing any of these, do not set CLASSPATH. If you have set
- it, unset it.
- Below you'll find examples for Windows (basic application class),
- Solaris (package class), javac (multiple packages), and browsers
- (applet codebase).
- -----------------------------
-
- Here's some Windows examples, assuming the application class is
-
- D:\src\tries\HelloWorld.class
-
- ## JDK 1.1, no CLASSPATH set
- > cd D:\src\tries\
- > D:\jdk11\bin\java HelloWorld
- # OK: 1.1 implicitly adds classes.zip and current dir
-
- > D:\jdk11\bin\jre HelloWorld
- # FAILS: jre does not automatically add . to CLASSPATH
-
- > cd D:\
- > D:\jdk11\bin\jre -cp D:\src\tries HelloWorld
- # OK: jre adds classes.zip, -cp adds class directory
-
- ## JDK 1.1, CLASSPATH set
- > set CLASSPATH=D:\src\tries
- > D:\jdk11\bin\java HelloWorld
- # OK: java using CLASSPATH
-
- > D:\jdk11\bin\jre HelloWorld
- # FAILS: jre does not use CLASSPATH (on Windows)
-
- ## JDK 1.0.2, CLASSPATH set
- > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
- > D:\jdk102\bin\java HelloWorld
- # OK:
-
- > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
- > D:\jdk11\bin\java HelloWorld
- # FAILS: exception in thread NULL - wrong system classes
-
-
- -----------------------------
-
- Here's some Solaris examples, assuming the application class is
-
- /usr/src/com/devjoes/killer/App.class
-
- and it is in package com.devjoes.killer:
-
- # JDK 1.1, no CLASSPATH set
- $ /usr/bin/jdk11/bin/jre -cp /usr/src com.devjoes.killer.App
- # OK:
-
- $ cd /usr/src/com/devjoes/killer/
- $ /usr/bin/jdk11/bin/java App
- # fails: class name and path are wrong
-
- $ CLASSPATH=/usr/src/
- $ /usr/bin/jdk11/bin/java App
- # fails: class name is com.devjoes.killer.App
-
- $ /usr/bin/jdk11/bin/java com.devjoes.killer.App
- # OK:
-
-
- -----------------------------
-
- Here's some javac examples, for both Solaris and Windows, based on the
- following:
- Source files package Makes the call
- /usr/src/pack/Minimal.java package pack pack.sub.Try.run()
- /usr/src/pack/sub/Try.java package pack.sub (nothing)
-
- $ CLASSPATH=""
- $ /usr/bin/jdk11/bin/javac /usr/src/pack/sub/Try.java
- # OK: works fine
-
- $ /usr/bin/jdk11/bin/javac /usr/src/pack/Minimal.java
- # FAILS: can't find pack.sub.Try
-
- $ cd /usr/src
- $ /usr/bin/jdk10/bin/javac pack/Minimal.java
- # OK: finds pack.sub.Try based on . as package root
-
- $ cd /usr/src/pack
- $ CLASSPATH=/usr/src
- $ /usr/bin/jdk11/bin/javac Minimal.java
- # OK: finds pack.sub.Try based on CLASSPATH
-
-
- Now assume the killer application class
-
- /usr/src/com/devjoes/killer/FastApp.java
-
- (in package com.devjoes.killer) uses a third-party package in a jar
- file
-
- /usr/jars/JShapes.jar
-
- but makes no other reference to other classes. The following works
- fine:
-
- $ CLASSPATH=/usr/jars/JShapes.jar
- $ cd /usr/src/com/devjoes
- $ /usr/bin/jdk11/bin/javac killer/FastApp.java
-
-
- Finally, some applet examples. Many applets only use one class, in the
- same directory as the html file:
-
- <applet code=ArcTest.class height=400 width=400>
-
-
- To use classes in subdirectory, use the codebase parameter:
-
- <applet codebase="mysubdir/" code=ArcTest.class ..
-
-
- To use classes in an archive, use the archive parameter:
-
- <applet archive="applets.jar" code=ArcTest.class ..
-
-
- See also: JDK 1.1 ReadMe
- Solaris JDK 1.1 tool documentation
- Win32 JDK 1.1 tool documentation
-
- 5. (Sect. 4) How do I do keyboard (interactive) I/O in Java?
-
- [*] Interactive I/O in Java is very poorly supported. Programmers must
- piece together several library classes in non-obvious ways to get the
- required functionality. See the answer to Question 6.1.
-
- 6. (Sect. 4) How do I do file I/O in an applet?
-
- [*] By default, an applet can read files on the server, but not write
- them, and has no access to the client. This is for reasons of security.
- It would be very unsafe to let any old applet that you downloaded from
- an unknown origin on the Internet read/write your files. It would be as
- unwise as allowing this kind of access to an ActiveX control (which is
- one reason ActiveX is dead on the Internet).
-
- There are several different ways to relax the default rules. See the
- answer to Question 7.8.
-
- 7. (Sect. 4) How do I do I/O to the serial port on my computer?
-
- [*] Java 1.0 and 1.1 do not have a serial port API. There are several
- commercially-available libraries that supply the needed functionality.
- JDK 1.2 introduces access to the serial and parallel ports as an
- extension (optional extra) library. See also the answer to Question
- 6.3.
-
- 8. (Sect. 4) How do I do formatted I/O like printf and scanf in C/C++?
-
- [*] The java.text package introduced with Java 1.1 supports formatted
- I/O. See also the answer to questions 7.11, 7.12, and 16.7.
-
- 9. (Sect. 4) I have spent more debugging time finding case (upper vs
- lower) typos than everything else put together and squared!
-
- [*] Do not forget that your remark must be phrased in the form of a
- question to win on FAQ Jeopardy. In any event, it is worth reminding
- those new to Java that letter case really matters in Java, and that the
- names of public classes should exactly match (including case) the names
- of the files they live in. See also the answer to Question 4.1.2
-
- 10. (Sect. 4) Why do I get this compiler error: "Can't make static
- reference to method..."?
-
- [*] Your code probably looks something like this:
-
- class myclass {
- public static void main(String args[]) {
- myMethod();
- }
-
- public void myMethod() {
- //some code
- }
- }
-
-
- The issue is this: a static method means it belongs to the class, not
- each individual object. If you leave the static keyword off (the usual
- case) as is done here with the method "myMethod()", it means that
- method can only be invoked on an object. But your call from main() has
- not told myMethod() which object it is to be invoked on. Inside a
- non-static method, you don't have to provide this information, as it
- assumes you mean the same object on which it was invoked. But when
- calling from a static method, you must provide the information, and you
- haven't - hence the error message.
-
- A common fix is to instantiate a member of the class, on which to
- invoke myMethod(), like this:
-
- public static void main(String args[]) {
- myclass m = new myclass();
- m.myMethod();
- }
-
-
- This problem is especially common when you are writing code that you
- want to run as an applet and as an application. Naturally, you call
- init() and start() from main. What you really need to do is:
-
- public static void main(String[] args) {
- Applet ma = new myApplet();
- ma.init();
- ma.start();
- }
-
-
- 11. (Sect. 4) Why can't I do myArray.length() ? Arrays are just objects,
- right?
-
- [*] Yes, the Java specification says that arrays are object references
- [JLS 10.2] just like classes are. However, arrays cannot contain
- methods. Instead you have to use myArray.length, which is a data item
- (not a method) called "length", belonging to myArray.
-
- 12. (Sect. 4) How do I close a Java window by using the icon in the upper
- right hand corner of a window?
-
- [*] Create an event handler class to extend WindowAdapter. Then
- override WindowAdapter's windowClosing() to do the actions you want
- when a window's "close" action is clicked. Then add that to the
- listeners for that window.
-
- import java.awt.*;
- import java.awt.event.*;
-
- public class MyFrame extends Frame {
- public MyFrame(String s) {super(s);}
-
- public class WL extends WindowAdapter {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- }
-
- // do your other Frame stuff
-
- }
-
-
- Somewhere in your initialization code, put:
-
- f1.addWindowListener( f1. new WL() );
-
-
- This last syntax is not commonly known to many people yet, it's another
- wacky artifact of inner classes.
-
- Alternatively, combining the inner class and setting the handler in one
- go, you could do this:
-
- MyFrame f1 = new f("wave");
-
- f1.addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- // and/or setVisible(false) and/or dispose()
- System.exit(0); }
- });
-
-
- See also the answer to questions 4.0.19, 4.0.30 and 15.7.
-
- 13. (Sect. 4) Why is b+=100; OK, but b = b+100; fails to compile?
-
- [*] You have code like this
-
- byte b = 0;
- Incompatible type for =. Explicit cast needed to convert int to byte.
- b = b + 100; // compiler error message
- ^
- b += 100; // works OK
-
- The reason is "promotion". Arithmetic expressions are promoted to the
- type of the longest, floatiest operand in them, or at least to int. The
- first statement involves the assignment of an expression. The
- expression is promoted to 32 bits, and must be cast back down to 8
- bits, like this "b = (byte) (b+100);". The second is an operator
- assignment, and the cast back to byte takes place automatically. The
- Java Specification says:
- "A compound assignment expression of the form E1 op= E2 is
- equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is
- the type of E1, except that E1 is evaluated only once" [JLS
- 15.25.2]
-
- The compile-time narrowing of constants means that code such as:
-
- byte theAnswer = 42;
-
- is allowed, with no cast necessary. [JLS 5.2]
-
- 14. (Sect. 4) How do I add two Float objects together?
-
- [*] You want to write code like this
-
- Float One;
- Float Two;
- Float Hard = One + Two;
-
-
- but the compiler does not allow it.
-
- Java has two separate ways of representing a 32 bit floating point
- number, Float and float. Float is a class, that whose sole purpose is
- to "wrap" a floating point number so it can be treated as an object.
- The class does not support floating point arithmetic, because the
- performance would be too slow. float is a primitive type (like int)
- that is used for floating point arithmetic.
-
- You choose one or the other depending on your predominant use. If all
- you need of your floating point numbers is arithmetic, declare them to
- be "float". If you need to use them as objects, for example to place
- them in a Vector, declare them as "Float".
-
- If you need both, tough. You have to declare them one way and convert
- whenever you need the capabilities of the other. Your specific code can
- be written as:
-
- Float One = new Float(1.0);
- Float Two = new Float(2.0);
- Float Hard = new Float(One.floatValue() + Two.floatValue());
-
-
- See also questions 3.8 , 5.1, and 10.1.
-
- 15. (Sect. 4) How can I put all my classes and resources into one file and
- have java run it?
-
- [*] Use a JAR file. Put all the files in a JAR, then use the jre to run
- the app, like:
-
- jre -cp app.jar Main
-
-
- assuming the jar is called app.jar and it has a class called Main that
- has the main() method for the application.
-
- 16. (Sect. 4) How can I see line numbers in a stack trace using JDK 1.1.6?
-
- [*] After switching from JDK 1.1.5 to JDK 1.1.6, the stack trace of
- uncaught exception no longer has source code line numbers. It only says
- <Compiled Code>.
-
- To see the line numbers where your program throws an exception, use the
- -nojit option to turn off the Just In Time compiling. One correspondent
- suggests that this is only in jre, not java.
-
- Another correspondent says that the environment variable JAVA_COMPCMD
- can be set to the following values:
- FORCE_SIGNON - shows JIT version
- DISABLE - disable the JIT
- STACKTRACE - shows "some" line numbers
-
- -----------------------------
-
- Windows-Specific
-
- 17. Is there a Java implementation for Windows 3.1?
-
- [*] Yes. See Question 1.6 It's not that great though because Windows
- 3.1 has inadequate features to support great software.
-
- 18. (Sect. 4) I'm using Win95, and my DOS window won't accept filenames
- longer than 8.3.
- "This program cannot be run in DOS mode"
-
- [*] Both these problems are resolved by the same process. Assuming
- you're running the Win95/98 command.com, then you've changed the MS-DOS
- Prompt options under the "Properties" menu item. In the Properties
- dialog, Program->Advanced gets you a dialog. Here, make sure the
- "Prevent MS-DOS-based programs from detecting Windows" checkbox is
-
- If the option is checked you get exactly the kind of behavior you're
- seeing. The option is unchecked by default, so it must have been
- selected at some time in the past. Change it back to unchecked.
-
- 19. (Sect. 4) I'm using Notepad to edit my files, and how can I save them
- with the extension ".java"? Also, in notepad some source files have all
- the characters on one line. Why is that?
-
- [*] First answer: put the entire filename in quotes in the save dialog.
- Once you have created your first Java file, double click on it in
- Explorer, select "Notepad" from the "Open with" box, and Notepad will
- stop adding the spurious ".txt" to your .java files.
-
- Second answer: Notepad expects to see a "carriage return/line feed"
- pair at the end of each line, rather than just the "newline"
- (line-feed) commonly used on Unix. Use this program to expand all
- newlines,
-
- /*
- * Usage: jre crlf file1.java file2.java ... fileN.java
- */
-
- import java.io.*;
- class crlf {
- public static void main(String s[]){
- byte b[]; byte p;
- FileInputStream is;
- BufferedOutputStream os;
- File f;
- for (int i=0; i < s.length;i++){
- try{
- f=new File(s[i]);
- b=new byte[(int)f.length()];
- is = new FileInputStream(f);
- is.read(b); is.close();
- os = new BufferedOutputStream(
- new FileOutputStream(s[i]),b.length);
- p='?';
- for(int j=0; j < b.length; j++){
- if((p!='\r')&&(b[j]=='\n')) os.write('\r');
- p=b[j]; os.write(p);
- }
- os.flush(); os.close();
- }catch(IOException e){
- System.err.println(e.toString());
- }
- }
- }
- }
-
-
- The source code is to show new users a way to make a simple program
- which can read a file and write it out buffered.
-
- Compile with "javac crlf.java" and run with
- java crlf outfile.txt
- or just use Wordpad instead of Notepad. Wordpad is under
- Start->Programs->Accessories->WordPad
-
- 20. (Sect. 4) What's J++6?
-
- [*] It is an abbreviation for "Microsoft J++ version 6". Microsoft
- launched J++ 1.0 in 1996 and it was compatible with Java 1.0. When Java
- 1.1 came out, Microsoft decided not to support key parts of it, such as
- JNI, JFC, RMI, and Java Beans. Nevertheless, Microsoft moved the
- version number of J++ to 1.1, which confused people who expected it to
- support JDK 1.1
-
- Microsoft has continued its attempt to fragment and undermine support
- for Java with J++6. First, it bumped the version number up, skipping
- over releases 1.2 , 3, 4, and 5. This aligned the number with other MS
- products, but falsely conveys the impression that J++6 is an equally
- stable and mature product. (A similar thing ocurred with NT, which was
- introduced at version 3.1, not version 1.0). Then Microsoft introduced
- two new keywords ("delegate" and "multicast"), as well as the
- complexity of conditional compilation and conditional methods.
-
- Microsoft's SDK has been moved further and further from standard Java
- with each successive release. J++ combined with the visual editor
- generates calls to the Windows-only WFC library. Anyone writing Java
- code that uses VJ++6 is needlessly restricting their programs to only
- ever run on Microsoft platforms. Microsoft has been cut off from future
- Java technology, so they do not have JNI, JFC, RMI, Java Beans,
- IIOP/CORBA hooks, Swing, PLAF & Accessibility, the Security API, Drag N
- Drop, among other features. If you like Java, you should encourage
- Microsoft to be compatible by not using their divergent tools.
-
- The entire purpose of VJ++ is to get people producing near-Java code
- that only runs on Windows. The strategy is being challenged in the law
- courts, giving VJ++ an uncertain future. So please use one of the other
- free or inexpensive standard IDEs for Windows instead. See a list of
- IDEs in this FAQ.
-
- You may see some programmers refer to J--. By this they mean
- Microsoft's incompatible J++ SDK.
-
- 21. (Sect. 4) How do I fix the message about "out of environment variable
- space"?
-
- [*] This occurs under Windows when you have long CLASSPATH names. You
- need to increase the enviroment space. Put this in your config.sys:
-
- shell=command /e:4096
-
-
- -------------------------------
-
- 5. Compiler Messages
-
- Most of the "questions" in this section are diagnostic messages from
- the compiler. Each answer explains what the message means, and how to
- avoid it.
-
- 1. (Sect. 5) Why did I get an OutOfMemory error when porting working code
- from JDK 1.0.2 to 1.1?
-
- [*] The preset memory limit has changed. It went down to 16MB so as not
- to penalize low memory machines. You can adjust it with
-
- java -mx32m Frotz
-
- to get a 32MB extent.
-
- Also see the Runtime methods freeMemory() and totalMemory().
-
- 2. (Sect. 5) Why do I get a "Statement not reached" error from javac for
- no apparent reason?
-
- [*] JDK 1.0 has a limit of 63 words of storage for local variables in
- any method. longs and doubles require two words of storage, and all
- other primitive types and all reference types require one word. If you
- assign values to more than 63 words of local variables, you will get a
- "Statement not reached" error on the statement after you assign to the
- variable that contains the 64th word. In JDK 1.1, the low limit was
- removed.
-
- 3. (Sect. 5) class MyOrdinaryClass must be declared abstract.
- It does not define void actionPerformed(java.awt.event.ActionEvent)
-
- [*] This is one of those error messages where the compiler tries to
- guess what you meant, and gives you a message based on a wrong guess!
- So the message is confusing.
-
- Your MyOrdinaryClass class implements ActionListener, which means you
- must include a definition of the methods from the ActionListener
- interface.
-
- But you did not. You either left a method out, or (more likely) you
- misspelled its name. Perhaps you wrote "ActionListener" instead of
- "actionListener".
-
- So the compiler did not find the method to fulfill the interface. Since
- there was a method promised but not supplied, the compiler thinks you
- were aiming at an abstract class, and it prints an error message
- accordingly.
-
- 4. (Sect. 5) Variable may not have been initialized.
-
- URL test;
- try {
- test = new URL("http://osprey.avs.dec.com");
- } catch (MalformedURLException e) {
- System.out.println("bad URL:" + e.getMessage());
- }
- System.out.println("this is url " + test);
-
-
- [*] The compiler will warn you if you use a variable before it is
- certain to have been initialized (not just with the default value)
- since this means you probably forgot to set it.
-
- In the case of exceptions, you have to consider that the flow of
- control may terminate abruptly, with no operations completed. In the
- example above, if an exception is raised in the try clause, variable
- test will not be assigned a value, yet you are using it after the catch
- clause. One solution would be to declare test with an explicit initial
- value of null, but this works only because toString() works on a null
- reference. (toString() is invoked implicitly by operator + with String
- operand.)
-
- Always initialize to a value that will work notwithstanding exceptions
- being thrown.
-
- 5. (Sect. 5) No constructor {superclass}()
- I extended the class called Frotz, and the compiler is giving me an
- error message "No constructor Frotz()" in the child class. Why?
-
- [*] When you define a constructor for a class, the compiler inserts a
- call to the superclass' parameterless constructor unless you explicitly
- call the superclass' constructor at the start of your constructor. If
- the superclass doesn't *have* a parameterless constructor, the compiler
- emits a message to that effect. The solution is usually to call the
- superclass' constructor at the start of your constructor.
-
- 6. (Sect. 5) No constructor matching MyCheckbox(myApplet)
-
- MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
- found in class MyCheckbox.
-
- bp1 = new MyCheckbox(this);
- ^
-
- [*] If a compiler isn't finding a constructor you thought you created,
- check whether you gave a return value to the method (remember,
- constructors have no return value). E.g.,
-
- public void MyCheckbox( Container parent )
-
-
- If you did, the compiler will think it is an ordinary method, not a
- constructor. This is a common mistake and hard to spot.
-
- 7. (Sect. 5) Type expected {public method variable}
-
- public static void main(String[] args) {
- ^
- Statement expected.
- public static final float Conversion_Factor = 39.37;
- ^
- Type expected.
-
- [*] Argument and variable declarations inside methods are never public
- or static because they are local to a method. (Before JDK 1.1 they
- couldn't be final either, but there was no good reason for that
- restriction and it was dropped.) If you have public or static
- variables, move them outside the method. They are usually put at the
- beginning of the class.
-
- 8. (Sect. 5) Can't access protected method clone in class java.lang.Object
-
- T.java:96: Can't access protected method clone in
- class java.lang.Object. OtherT is not a subclass of
- the current class.
-
- [*] Object.clone() is protected because subclasses might want to
- restrict access to cloning, and if Object.clone() were declared public,
- subclasses could never make it more restrictive. The subclass can make
- access to the clone() operation less restrictive.
- This means that a method can clone its own objects, but a method cannot
- clone objects of another class, unless you do something like:
-
- class SomeObject implements Cloneable {
- public Object clone()
- throws CloneNotSupportedException {
- return super.clone();
- }
- }
-
-
- i.e., override clone() to make it public, and call the superclass
- clone().
-
- class Foo {
- Bar bar;
- Foo (Bar b) {
- try {bar = (Bar) b.clone();}
- catch (Exception e) {}
- }
- ...
- class Bar implements Cloneable {
- public Object clone()
- throws java.lang.CloneNotSupportedException {
- return super.clone();
- }
- }
-
-
- Another refinement is to note that Object.clone() only throws a
- CloneNotSupportedException when the object doesn't implement Cloneable.
- Since you control what your classes do and don't implement, you can
- ensure that Cloneable classes implement the interface, and you don't
- need to make the overridden clone() throw the exception.
-
- public class X implements Cloneable {
- public Object clone() { // no throws
- try {
- // in case members need cloning
- X c = (X)super.clone();
- return c;
- } catch (CloneNotSupportedException e) {
- // should not happen, because of Cloneable
- throw new InternalError();
- }
- }
- }
-
-
- 9. (Sect. 5) Deprecated methods
- What does "deprecated" mean? I got this in a compiler error message.
-
- [*] "Deprecated" means you are using an older API, that Sun has
- replaced with a newer one (usually to follow more consistent naming
- conventions). Deprecated methods are not recommended for use. They are
- supported in the short term, but your code should be updated with the
- new. To update your code, compile your old code using javac's
- "-deprecation" option to list deprecated methods, then find the
- replacement methods in the current HTML API documentation for the old
- deprecated methods.
- As an example of a deprecated API, Component.size() was replaced by
- Component.getSize().
-
- See also
- http://java.sun.com/products/jdk/1.1/docs/guide/
- misc/deprecation/index.html, "1.1 Deprecated Methods"
- and
- http://java.sun.com/products/jdk/1.1/docs/guide/
- awt/DeprecatedMethods.html, "Deprecated methods in the 1.1 AWT"
-
- 10. (Sect. 5) double y = sin(90);
- What's wrong? That code provokes compiler messages.
-
- [*] You need to write it this way:
-
- double cvtDegToRad = Math.PI/180;
- double x = 90*cvtDegToRad;
- double y = Math.sin(x);
-
-
- sin is a static method of the Math class that takes radians. You need
- to use the "Math" classname, e.g. Math.sin instead of plain sin,
- because you have to say what class or object these methods belong to.
-
- A very common mistake is to assume that importing a class means that
- you don't have to qualify the names of its members. When you call a
- method you have to state the name of the class or object it belongs to,
- regardless of any imports you have done. (Except inside the class
- itself, obviously).
-
- The trig functions are static methods of the Math class, so you give
- the name of the class in invoking them. Further, the Math class works
- in radians, not degrees. 360 degrees = 2 pi radians, so use a
- conversion factor as shown if you are working with degrees.
-
- 11. (Sect. 5) Can't make static reference to method...
-
- [*] Your code probably looks something like this:
-
- class myclass {
- public static void main(String args[]) {
- myMethod();
- }
- public void myMethod() { //some code
- }
- }
-
-
- Static (class) methods can only call without qualification other static
- methods, so you either have to qualify the call in (static) main() to
- (nonstatic) myMethod() with an object of type myclass, or you have to
- make myMethod() static.
-
- People often forget that even though main is "in" myclass, there is no
- implicit object when you are in main() because it is static. This
- happens especially when writing code to run an applet as an
- application, where you want to call init() and start() from main.
-
- public static void main(String[] args) {
- Applet ma = new myApplet(); // have to create object
- ma.init(); // use to qualify access to non-static methods
- ma.start();
- }
-
-
- 12. (Sect. 5) Incompatible type for =. Explicit cast needed...
-
- byte b = 0;
- Incompatible type for =.
- Explicit cast needed to convert int to byte.
- b = b + 100; // compiler error message
- b += 100; // works OK
-
-
- [*] Arithmetic expressions are promoted to the type of the longest,
- floatiest operand in them, or at least to int. The first statement
- involves the assignment of an expression. The expression is promoted to
- 32 bits, and must be cast back down to 8 bits, like this: b = (byte)
- (b+100); The second is an operator assignment, and the cast back to
- byte takes place automatically. The Java Language Specification says
- that a compound assignment expression of the form E1 op= E2 is
- equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the
- type of E1, except that E1 is evaluated only once. (See JLS 15.25.2
- Compound Assignment Operators) The compile-time narrowing of constants
- means that code such as:
-
- byte theAnswer = 42;
-
-
- is allowed, with no cast necessary. (See JLS 5.2 Assignment Conversion)
-
- Other sites:
- JLS 5.2 Assignment Conversion
- JLS 15.25.2 Compound Assignment Operators
-
- 13. (Sect. 5) Class {package}.{class} not found in type declaration.
- I am trying to compile file "{class2}.java" in a package, and I get
- this compiler error. {class2}.java refers to {package}.{class}, but the
- file {class}.java and {class2}.java are in the same {package}
- directory, which is the current directory and which is in the CLASSPATH
- variable. Both files have "package {package};" at the top of the file.
- What's the problem?
-
- [*] When the source refers to classes in packages, the CLASSPATH has to
- point to the root of the package/directory hierarchy for a reference to
- resolve correctly. This is true even for source files in the same
- package (and directory). I.e., assuming {class} and {class2} are both
- in {package}, {class} can't make a reference to {class2} unless the
- CLASSPATH is set so javac can find {package}/{class2}.java. It should
- make no difference what directory you are in when you invoke javac,
- unless you are relying on "." in the CLASSPATH to point to the package
- root or are specifying the source file with a relative path (e.g.,
- {package}/{class}.java).
-
- Some examples, assuming
- o - Foo.java and Bar.java are in /java/source/pack/
- o - Both have "package pack;" as the first statement
- o - Foo.java includes "Bar b = new Bar();"
-
- # solaris ksh
- $ alias jc=/java/jdk11/bin/javac
- $ CLASSPATH=/java/source/
- $ jc /java/source/pack/*.java # works fine
- $ cd /java/source/pack
- $ CLASSPATH=.
- $ jc *.java # fails - Foo.java can't find class Bar
- $ cd .. # now . is package root, /java/source/
- $ js pack/*.java # works
-
-
- 14. (Sect. 5) public class "Foo" must be defined in "Foo.java"
- I get this message even though it is in Foo.java. What gives?
-
- [*] Javac verifies that a public class is defined in a file of the same
- name (e.g., that public class Foo is defined in Foo.java). Two things
- you can check:
-
- First, make sure the case matches exactly. public class Foo cannot be
- in foo.java; it has to be in Foo.java.
-
- Second, are you using MKS on win32? Javac on win32 assumes you are
- using the DOS path separator (\) even though MKS accepts the Unix path
- separator (/). When javac tries to parse a your Unix-style path, it
- won't produce the correct filename, the match will fail, and it will
- emit an error. You have to use the DOS path separator (\), which must
- be escaped in MKS - e.g., "javac H:\\source\\package\\Foo.java".
- Alternatively, you can traverse to each source directory and avoid
- pathnames altogether.
-
- -------------------------------
-
- 6. Java Language Issues
-
- How-to
-
- 1. (Sect 6.) How do I compare two Strings?
-
- if (s1 == s2)
-
- is giving me funny results.
-
- [*] The comparison using "==" on objects, such as Strings, is asking,
- "Do these two objects have the same reference?" Do they have the same
- address, and hence are the same object? What you really want to do is
- ask, "Do these two Strings have the same *contents*?"
- Compare String contents with any of the following:
-
- if (s1.equals(s2) )
- if (s1.equalsIgnoreCase(s2) )
- if (s1.startsWith(s2) )
- if (s1.endsWith(s2) )
- if (s1.regionMatches(s1_offset, s2, s2_offset, length) )
- if (s1.compareTo(s2) < 0)
-
-
- (There are other ways, too.)
- Note that you can do this with literals:
-
- if ("apple".equals(s2) ) ...
-
-
- If you compare these the other way round, like this:
-
- if ( s2.equals("apple") ) ...
-
-
- and s2 is null, you will get a null pointer exception.
-
- 2. (Sect. 6) How do you get the code value of a char?
- I would like to transform a char into the corresponding int value, that
- represents the code value of the char. How?
-
- [*] Like this.
-
- char c = 'A';
- int i = c;
-
-
- Going the other way is just
-
- c = (char) i;
-
-
- This question crops up so frequently because the BASIC language uses
- functions to map characters into ints, ASC( 'A' ) => 65 causing BASIC
- programmers to seek the corresponding Java functions. The same is true
- for Pascal, Ada, and other languages.
-
- 3. (Sect. 6) Why does b >>>= 1 give me the same result as b >>= 1?
-
- [*] ">>" is a "signed" or "arithmetic" shift, namely, it replicates the
- sign bit on the left as it shifts.
- The ">>>" operator is an "unsigned" or "logical" shift; it does a shift
- right and zero fill. However, ">>>" looks like it does a signed shift
- with negative bytes and shorts, where int promotion alters the sign.
-
- This occurs when you have a non-canonical type, byte, or short, with a
- negative value, e.g.
-
- byte b = -15; // 0xf1
- b = (byte) b >>> 4; // why isn't b 0x0f ?
-
-
- The initial expectation is that an unsigned shift right of 0xf1 would
- successively be (in binary)
-
- 0111_1000 then
- 0011_1100 then
- 0001_1110 then
- 0000_1111
-
-
- But that doesn't happen. The rules of arithmetic in Java say that all
- operands are converted at least to int before the operation (and
- possibly to a more capacious type). That means our byte is promoted to
- an int, so instead of shifting 0xf1, we are shifting 0xfffffff1. If you
- shift right unsigned 4 places, you get 0x0fffffff. When you cast that
- to a byte it becomes 0xff, or -1.
-
- The bottom line is that the final result is the same as if you had
- performed the signed shift because the unsigned shift applied to the
- intermediate int, not to the original byte. This anomaly means that
- ">>>" is useless for negative bytes and shorts. It is probably safer
- and clearer not to use it at all, but to mask and shift instead:
-
- // not recommended
- byte b = -15;
- b = (byte) (b>>>4);
- System.out.println("b= "+Integer.toHexString(b) );
- // recommended
- b = -15;
- b = (byte) ( (b & 0xFF) >> 4 );
- System.out.println("b= "+Integer.toHexString(b) );
-
-
- 4. (Sect. 6) Why does the <unexpected> happen in floating point?
-
- [*] There are several unexpected things that seem to bite programmers
- with floating point. This is almost always a result of the programmer
- not being fully conversant with floating point arithmetic in general,
- rather than a problem relating to Java.
-
- If you seem to be having problems with floating point, the problem
- probably stems from the fact that floating-point arithmetic is
- inherently imprecise. You can expect up to 7 digits of precision with
- floats and 16 digits with doubles. However, that does not mean that a
- number that can be exactly represented in 7 digits decimal or can be
- exactly represented as a binary floating point number. On the contrary,
- that is usually not the case.
-
- Additionally, when Java converts floating point numbers to a String, as
- is done when they are output, enough digits are printed so the number
- can be read back in with no loss of precision. For this reason, you may
- see more "inaccuracies" in floating point output than you are used to.
- This policy actually gives you more consistent results than on a system
- where floating point output is deliberately rounded to make the output
- "pretty".
-
- There is a limitation of FP in JDK 1.0 (fixed in JDK 1.1). Namely, when
- you output a floating point number in Java 1.0, the result is
- system-dependent and contains no more than six digits after the decimal
- point. This bug is fixed in Java 1.1.
-
- For more information and detailed specifications on how Java deals with
- floating point, see the URLs listed below.
-
- Other sites:
- What Every Computer Scientist Should Know About Floating Point.
- http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities
-
- JLS 4.2.3 Floating-Point Types and Values
- JLS 4.2.4 Floating-Point Operations
- JLS 3.10.2 Floating-Point Literals
- JLS 5.2.3 Narrowing Primitive Conversions
-
- If you want the rounded floating point output that most languages have,
- use the new java.text package of Java 1.1 to limit the number of digits
- that are output. If you need more precision than about 16 digits, use
- the BigInteger and BigDecimal classes of Java 1.1.
-
- Understanding the Java Language
-
- 5. (Sect. 6) How can I program linked lists if Java doesn't have pointers?
-
- [*] Of all the misconceptions about Java, this is the most egregious.
- Far from not having pointers, in Java, object-oriented programming is
- conducted exclusively with pointers. In other words, objects are only
- ever accessed through pointers, never directly. The pointers are termed
- "references" and they are automatically dereferenced for you.
-
- Java does not have pointer arithmetic or untyped casting. By removing
- the ability for programmers to create and modify pointers in arbitrary
- ways, Java makes memory management more reliable, while still allowing
- dynamic data structures. Also note that Java has NullPointerException,
- not NullReferenceException.
-
- A linked list class in Java might start like this:
-
- public class LinkedList {
- public LinkedList head;
- public LinkedList next;
- public Object data;
- public LinkedList advanceToNext(LinkedList current) { ...
- }
-
-
- Another choice for a linked list structure is to use the built-in class
- java.util.Vector which accepts and stores arbitrary amounts of Object
- data (as a linked list does), and retrieves it by index number on
- demand (as an array does). It grows automatically as needed to
- accommodate more elements. Insertion at the front of a Vector is a slow
- operation compared with insertion in a linked list, but retrieval is
- fast. Which is more important in the application you have?
-
- 6. (Sect. 6) Are parameters in Java passed by value or by reference?
-
- [*] All parameters (values of primitive types and values that are
- references to objects) are passed by value. (See JLS 8.4.1 Formal
- Parameters) However this does not tell the whole story, since objects
- are always manipulated through reference variables in Java. Thus one
- can equally say that objects are passed by reference (and the reference
- variable is passed by value). This is a consequence of the fact that
- variables do not take on the values of "objects" but values of
- "references to objects" as described in the previous question on linked
- lists.
-
- Bottom line: The caller's copy of primitive type arguments (int, char,
- etc.) _do not_ change when the corresponding parameter is changed.
- However, the fields of the caller's object _do_ change when the called
- method changes the corresponding fields of the object (reference)
- passed as a parameter.
-
- Also in this FAQ:
- How can I program linked lists if Java doesn't have pointers?
- Other sites:
- JLS 8.4.1 Formal Parameters
-
- 7. (Sect. 6) What are "class literals"?
-
- [*] A feature introduced in JDK 1.1. They are literals of type "Class"
- that hold a value representing any class. There are even values to
- represent "void" and an array, like this:
-
- Class myCl1 = Character.class;
- Class myCl2 = Void.class;
- Class myCl3 = Object.class;
- Class myCl4 = String[].class;
- Class myCl5 = int[][].class;
-
-
- You might use it like this:
-
- Class cl = thing.getClass();
- if (cl.equals(myCl1))
- System.out.println("It's a Character class");
-
-
- Note that a class literal
-
- Component.class
-
-
- is the equivalent of
-
- Class.forName("java.awt.Component")
-
-
- The second can throw an exception, but the first cannot. If you don't
- know the name of the class when you write the code, you cannot use the
- first form.
-
- 8. (Sect. 6) What are the naming conventions in Java?
-
- [*] The naming conventions are straightforward:
- 1. Package names are guaranteed uniqueness by using the Internet
- domain name in reverse order: com.javasoft.jag - the "com" or
- "edu" (etc.) part used to be in upper case, but now lower case is
- the recommendation.
- 2. Class and interface names are descriptive nouns, with the first
- letter of each word capitalized: PolarCoords. Interfaces are often
- (not always) called "something-able", e.g. "Runnable", "Sortable".
- Caution: java.util.Observable is not an interface, though
- java.util.Observer is. These two are poorly designed.
- 3. Object and data (field) names are nouns/noun phrases, with the
- first letter lowercase, and the first letter of subsequent words
- capitalized: currentLimit
- 4. Method names are verbs/verb phrases, with the first letter
- lowercase, and the first letter of subsequent words capitalized:
- calculateCurrentLimit
- 5. Constant (final) names are in caps: UPPER_LIMIT
- 6. Also in the FAQ:
- Where can I find a Java style guide on naming conventions?
- Other sites:
- JLS 6.8 Naming Conventions
-
- 9. (Sect. 6) Should I prefer importing {package}.{class} over {package}.*?
-
- Does it make a difference to the class file in any way, if I import a
- package versus use the full name, i.e.
-
- import java.rmi.server.*;
- ...
- RemoteObject ro;
-
- versus:
-
- java.rmi.server.RemoteObject ro;
-
- [*] No, it makes no difference to the class files or runtime speed.
- Import is just a shorthand for quoting the full name package and class
- name (as in the examples in the question). Importing a class does not
- cause the class to be loaded at run time. There is no runtime penalty
- for using the * form of import. The class file will contain the name of
- the packages it uses, and the loader will look for those classes as
- needed at runtime.
-
- At compile time, the different forms of import may or may not make a
- difference to compile time. Such a difference is likely to be
- negligible, and should not be a factor in which form of import you use.
-
- However, there are style advantages. Some say that stating which
- classes you are importing can help program readability. In a program
- with many * import statements, it may take a programmer time to find
- which package an obscure class is imported from. If you explicitly list
- each class you import at the top of the program, you document which
- package each class you use comes from. These people suggest that you
- use
-
- import java.rmi.server.RemoteObject;
-
-
- in preference to:
-
- import java.rmi.server.*;
-
-
- Other people say that it is clearer still to use the full package and
- class name, at the point where you use classes in other packages.
- These people suggest that you use:
-
- java.rmi.server.RemoteObject ro;
-
-
- But that gets a little lengthy when you instantiate:
-
- java.rmi.server.RemoteObject ro
- = new java.rmi.server.RemoteObject();
-
-
- You always have the option of stating the full package and class name,
- whether you use import or not.
-
- Another good reason not to use the * form is when you are importing two
- packages that have classes of the same name and you want to use only
- one of those classes. E.g.
-
- import com.sun.*;
- import com.ms.*;
-
-
- where there is a class called Modem in both those packages. If you use
- the * form of import, you import both of the Modem classes and then
- must fully qualify the class each time you use it, to say which of the
- two you mean.
-
- In Java 1.0, if you import a class that has the same name as a class
- defined in that source file, you will get an error that the class names
- clash. In Java 1.1, the local class will be used when the package name
- is not given; to use the imported class, you have to use the full
- package name.
-
- The best advice is to write the program so that it is as readable as
- possible. Where you have a group of well-known classes, as in java.awt,
- there is no reason not to use "import java.awt.*;"
-
- 10. (Sect. 6) How can I use Math.cos() etc. without the prefix "Math."?
- Is there some declaration that I can use to make "acos", "cos", "sin",
- etc. (from java.lang.Math) recognizable in my own class, so I don't
- have to prefix "Math." to them?
-
- [*] No. There is no good alternative. There are several bad
- alternatives:
- 1. Using "import" doesn't work.
- The import stament only imports packages, subpackages, and
- classes, not class members. This doesn't work:
-
- import java.lang.Math.*;
-
-
- 2. Minimizing class name usage is unclear and bad style.
- - You could wrap the functions in your own class.
-
- double sin(double x) {
- return Math.sin(x);
- } // etc. for each function
-
-
- But you'd have to use your class name everywhere but inside your
- class, so it doesn't help.
- - You can make a null reference to the Math class and use it to
- refer to the static methods. Declare
-
- java.lang.Math M = null;
- angle = M.cos(i);
-
-
- Besides not being clear, this invites abuse and errors.
-
- - You could inherit the names
- If java.lang.Math were not final and your class did not extend
- another class, you could have your class extend Math, to bring the
- namespace in. However, it is poor OOP style to use inheritance to
- obtain a name abbreviation rather than to express a type
- hierarchy.
-
- 11. (Sect. 6) Why is there a standard JNI?
-
- [*] JNI is the Java Native Interface. It defines the way that a Java
- program can call C programs. The industry has agreed on, and Sun has
- codified, JNI as the standard. Microsoft shuns the standard and uses a
- protocol of its own called Raw Native Interface, RNI.
-
- You might think that once a Java program uses JNI, portability is lost,
- and hence it doesn't matter if vendors diverge from the JNI standard.
- Not so. Code that accesses a native library using JNI can run on any VM
- that supports JNI, so it's portable across VMs on the same platform.
- Further, you can port a native library to all platforms Java supports
- (indeed, this is how Sun implements the Java Platform), so JNI
- _enables_ cross-platform development where it's necessary to use
- platform-specific idioms for certain functionality.
-
- Conversely, code that uses RNI can only run on Microsoft's VMs on the
- win32 platform. Microsoft's RNI has the effect of limiting RNI programs
- to the Microsoft VM. Further, Microsoft's failure to support JNI locks
- out JNI-based functionality on Windows. Microsoft's non-standard RNI is
- the reason that programs using the Microsoft JVM cannot use the
- standard Java jdbc-odbc library. That library has a piece written in C.
- It works for all JVMs except Microsoft's.
-
- The standard JNI thus has two purposes:
- 1. Source code compatibility between different platforms.
- 2. Binary code compatibility between different JVMs on the same
- platform.
- Microsoft's use of RNI locks in programmers who use it, and Microsoft's
- failure to support JNI locks out programmers who don't use RNI. Users
- can't run standard JNI applications on Microsoft VMs, or RNI
- applications on non-Microsoft VM's. As a result, since most users will
- support only one VM, they'll be locked in to complementary software -
- in the case of Microsoft, a proprietary standard. A standard JNI means
- that you can use any standard JVM to run your code on this platform.
-
- 12. (Sect. 6) How do I find out more about JNI? How do I find out more
- about Java Anything?
-
- [*] Taking the questions one at a time. Use of JNI detracts from
- program portability. So you would only do it when you need some
- critical single-platform effect. The documentation on JNI is at:
- http://java.sun.com/docs/books/tutorial/native1.1/index.html
-
- If your interest extends to reading a book on JNI, a good one is
- "Essential JNI Java Native Interface" by Rob Gordon; ISBN
- 0-13-679895-0. Available from Amazon.com and book outlets everywhere.
-
- In general, if you want to find out about topic "X" in Java, your first
- stop should be to search the http://java.sun.com website for "X". For
- example if you want to know about Internationalization in Java, a
- search at the site quickly takes you to
- http://java.sun.com/products/jdk/1.1/docs/guide/intl/intlTOC.doc.html.
-
- 13. (Sect. 6) How do I get unsigned ints in Java?
-
- [*] Java doesn't have unsigned ints. The reason is that this is a
- poorly designed area of C. The rules for what type you end up with when
- you mix signed and unsigned in expressions are complicated, and they
- changed between K&R and ANSI C (you might have heard this under the
- name "unsigned preserving vs. value preserving"). Worse, they depended
- on the underlying hardware, so they varied from platform to platform,
- causing bugs in all kinds of unexpected places. The book "Expert C
- Programming" goes into this in more depth (page 25). So, to avoid
- bringing over the hidden complexities, Java does not bring over
- unsigned types from C.
- Use type char if you are OK with 16-bit unsigned quantities. Otherwise,
- go to the next larger type and use masking. Specifically, to convert an
- int to its unsigned representation, use:
-
- ((long)i) & 0x00000000FFFFFFFFL
-
-
- This promotes the signed int to long (with sign extension) then chops
- off the sign-extension, leaving it as a positive 32-bit quantity held
- in a 64-bit type.
- Also worth noting is that if you're going to work with unsigned bytes,
- int is a more efficient larger type to use than short or char, since
- smaller values have to be promoted to int to do any arithmetic or
- testing on them.
-
- 14. (Sect. 6) What happened to "private protected"?
-
- [*] It first appeared in JDK 1.0 FCS (it had not been in the betas).
- Then it was removed in JDK 1.0.1. It was an ugly hack syntax-wise, and
- it didn't fit consistently with the other access modifiers. It never
- worked properly: in the versions of the JDK before it was removed,
- calls to private protected methods were not dynamically bound, as they
- should have been. It added very little capability to the language. It's
- always a bad idea to reuse existing keywords with a different meaning.
- Using two of them together only compounds the sin.
-
- The official story is that it was a bug. That's not the full story.
- Private protected was put in because it was championed by a strong
- advocate. It was pulled out when he was overruled by popular
- acclamation.
-
- Inheritance
-
- 15. What are the differences between an interface and an abstract class?
-
- [*] Some use a semantic distinction: an abstract superclass models the
- "is" relationship, while an interface models the "has" relationship.
- The rule would thus be, if it's a subtype, inherit; otherwise,
- implement. But where the object boundaries are themselves at stake,
- it's circular to state this unless there are real-world metaphors to
- distinguish the objects from their properties and parents. So where
- there are no real-world metaphors, you have to understand the practical
- differences in Java (esp. vs. C++).
-
- Most differences between interfaces and abstract classes stem from
- three characteristics:
- 1. Both define method signatures that a derived class will have.
- 2. An abstract class can also define a partial implementation.
- 3. A class can implement many interfaces, but inherit from only one
- class.
-
- In greater detail, these topics are:
- 1. Method signatures Both interfaces and abstract classes permit one
- to treat the derived-type class as the derived-from-type class.
- Both define a set of available methods in a way that can be
- enforced by the type-checking mechanism. This is typically used to
- permit different (derived) types to behave in the same way (as
- what they are derived from - i.e., they all support particular
- methods). For example, all java.* types can be printed as Strings
- because Object, the superclass of all java.* types, has a
- toString() method. Similarly, all types that implement the
- Observable interface can be passed an Observer to signal when an
- event has occurred. This permits an algorithm or service to
- operate on different (derived) types as if they were the same
- (derived-from) type.
- This mechanism supports not only polymorphism (one object treated
- as another), but differentiation. In either case, the (derived)
- types can implement the method in the way appropriate to that
- type. However, you're not likely to override inherited
- functionality, but you must implement interface methods, so if you
- expect significant differentiation, then an interface might be
- warranted.
- Finally, this mechanism supports a weak variant of access control.
- Only inherited methods are available to callers who only have a
- reference to the superclass or interface type. It's weak because
- they can attempt a narrowing cast if they know their target type.
- Nonetheless, it reduces some complexity.
- 2. Inheriting implementation Inheriting an implementation is useful
- where the code should be shared. This happens where derived types
- vary the functionality only a little bit, or where a complex set
- of method interfaces can through mutual reference be implemented
- with relatively few methods that can be implemented by derived
- types. You can also reuse code by having your class use or keep an
- object of another type that implements that code, but that doesn't
- permit your callers to treat you in a particular way. To both
- "get" functionality and to be treated "as" the superclass are the
- essentials of the type/subtype relationship.
- 3. Java's rule of single inheritance Java differs from C++ in
- permitting only single inheritance. This makes for some difficult
- choices, if you would like to share combinations of inherited
- functionality and polymorphism from more than one source. However,
- it does reinforce the notion of inheritance as a subtyping (is)
- relationship, and implicitly that type relationships form a tree
- rather than a network.
-
- Other differences to consider:
- 1. Abstract class implementations may include fields
- 2. Interfaces may include final data members
- 3. It is slightly slower to call an implemented method via an
- a superclass method via a subclass reference (i.e., where the
- subclass does not override the method). There is almost no penalty
- for calling a subclass method via a superclass reference. (All are
- compared to a direct method call, i.e., calling the derived class
- method via a derived class reference).
-
- 16. (Sect. 6) How do static methods interact with inheritance?
-
- [*] Static (per-class, rather than per-object) methods do not
- participate in overriding (choosing the right method at runtime based
- on the class of the object). Probably the best and simplest way to
- think about this (and to write your code) is to write every invocation
- of a static method using the fully qualified class name:
-
- class A {
- public static method1() {
- A.method2();
- }
- public static method2() {
- }
- }
-
- class B extends A {
- public static method3() {
- A.method1();
- }
- public static method2() {
- }
- }
-
-
- Now it is perfectly clear that the static method2() that is called is
- A.method2(), not B.method2(). A.method2() will be called regardless of
- whether you use the fully-qualified class name or not, but using "A."
- makes it obvious to all.
-
- 17. (Sect. 6) Why is the String class final? I often want to override it.
-
- [*] Being final guarantees that instances of String are immutable. (The
- String class implements immutable objects, but if it were not final it
- would be possible to write a subclass of String which permitted
- instances to be changed.) Strings need to be immutable for efficiency
- and security.
-
- As for efficiency, Strings are very commonly used, even behind the
- scenes by the Java compiler. Efficiency gains in the String class yield
- big dividends. If no one can change a String, then you never have to
- worry about who else has a reference to your String. It's easier to
- optimize accesses to an object that is known to be immutable.
-
- Security is a more compelling reason. Before String was changed to be
- final (while Java 1.0 was still in beta) there was a race condition
- which could be used to subvert security restrictions. It had to do with
- having one thread change a pathname while another thread was about to
- open it.
-
- There are other ways to solve these problems, but the designers
- preferred making String final, particularly since the StringBuffer
- class is available as an alternative.
-
- 18. (Sect. 6) If I extend/subclass a class, are the constructors inherited?
-
- [*] "Constructor declarations are not members. They are never inherited
- and therefore are not subject to hiding or overriding." The default
- constructor is not inherited, but provided. (See JLS 8.6.7 Default
- Constructors)
-
- If you don't give your child class any constructors, a default no-arg
- constructor that invokes the superclass' constructor is provided for
- you. If the superclass doesn't have a no-arg constructor, you should
- create a constructor and call the appropriate superclass constructor.
-
- Also in the FAQ:
- Compiler message No constructor {superclass}()
-
- Other sites:
- JLS 8.6.7 Default Constructors
-
- 19. (Sect. 6) How can I safely store particular types in general
- containers?
- I often want to store particular types of objects but don't want to
- subclass my basic storage classes to enforce the particular type; that
- would make for too many subclasses (e.g., IntegerLinkedList,
- StringLinkedList, etc.).
-
- [*] Generic programming in java (the rough equivalent of C++'s
- templates) works reasonably well since all java classes are subclasses
- of Object. There is, however one potential problem - there is always a
- possibility that a generic container may contain different classes of
- objects.
-
- This naturally leads to the question of how to do this in a type-safe
- way. If you've created a generic LinkedList class, how can you be type
- safe without having to create a multitude of subclasses
- (IntegerLinkedList, StringLinkedList, etc.)?
-
- One way to handle this would be to offer up an additional constructor
- in your generic class that takes a parameter of type "Class" and uses
- that parameter along with Class's "isInstance" method to guarantee that
- Objects added to the container are the expected type.
-
- public class LinkedList {
- Protected Class type = Object.class;
-
- public LinkedList(Class type) { this.type = type; }
-
- public void addElement(Object element) throws Exception
- {
- if(!type.isInstance( element ))
- throw new Exception(
- "Expected element of type (" + type + ")" +
- " got element of type (" + element + ")" );
- ...
- }
- }
-
-
- Note that the comments in the source for isInstance() refer to a
- "specified Class parameter", suggesting that you are supposed to write
- something like:
-
- public void addElement(Object element) throws Exception
- {
- Class c = element.getClass();
- if(!type.isInstance(c))
-
-
- This works, but the documentation for isInstance is clear that the
- parameter should be an Object rather than a Class. Also, note that
- "Collections" are coming in JDK 1.2, and they provide a much safer and
- more extensible mechanism. More information about this is available at
- the Java Developer Connection at the Java website: http://java.sun.com/
-
- Method interfaces
-
- 20. How do I send a variable number of arguments to a method?
-
- [*]
- 1. (Easy) Use method overloading to support different parameters.
- This makes things easy on the caller but can get out of hand if
- you want to support a wide number and variety of parameter types.
- You should ask yourself if your code design is well-organized if
- you need to do this.
- 2. (More complicated) Use arrays. It's even possible to declare
- arrays inline as shown below:
-
- foo("A param",
- new Object[] {"param3", "param4", new Integer(5)} );
- // ...
-
- void foo(String param1, Object param2[]) {
- System.out.println(param1);
- for (int i = 0; i < param2.length; i++) {
- System.out.println(param2[i].toString());
- }
- }
-
-
- You can even pass arrays of arrays using this method. Of course,
- inside the method you need to be able to decode what the arguments
- are and how you use them.
- 3. Alternatively you can invent a class that just contains all the
- possible fields you might want to pass into a method (plus
- booleans to say if each field is set or not), and make an object
- of that class be a parameter to the method. You can return
- multiple values from a method the same ways; either have the
- method return an array or a wrapper object.
-
- However, remember the wise words of Professor Alan Perlis, "if your
- procedure has more than about half a dozen parameters, you probably
- forgot a few." Passing large numbers of arguments into a function
- suggests your function is badly organized.
-
- 21. (Sect. 6) How can I return a different object in a method parameter?
- How can I pass an object to a method, and have the method change the
- reference so it points to a different object back in the calling code?
-
- [*] There are two ways. The obvious way is "just add another level of
- indirection". Wrap the object in another class, whose purpose is simply
- to be passed as a parameter, allowing the nested object reference to be
- modified.
- The second alternative is a clearer variant of this. Pass in a single
- element array. Since arrays are objects, this works.
-
- void jfoo(Object ref[]){
- ref[0] = new Object();
- }
- ...
- Object kludge[] = new Object[1];
- kludge[0]= myObj;
- jfoo(kludge);
- if (kludge[0] == myObj) ...
- else ...
-
-
- Note that changing a global variable/object inside a method is an
- egregious programming practice; it usually violates basic OOP
- constructs.
-
- 22. (Sect. 6) How do I get multiple return values back from a method?
-
- [*] You can just have the function return a Vector. This is
- particularly convenient when you're not sure how much you are going to
- be returning, based on what occurs in the method. A Vector is
- essentially a dynamically-growable array. Regular arrays can't grow
- after you declare them - you have to declare a bigger array and move
- the old stuff into it.
-
- Arrays
-
- 23. (Sect. 6) How do I allocate a multidimensional array?
-
- [*] There are several ways. If you want a rectangular array, you can
- allocate the space for the array all at once. The following creates a
- 4x5 array:
-
- int arr[][] = new int[4][5];
-
-
- If you want each row to have a different number of columns, you can use
- the fact that a two-dimensional array is actually an array of arrays.
- The following code allocates a triangular array:
-
- int arr[][] = new int[4][]; // allocate the four row arrays
- for (int i = 0; i < 4; i++) // initialize each of the four rows
- arr[i] = new int[i + 1]; // row i has i + 1 columns
-
-
- Note that if you allocate an array of any kind of object (as opposed to
- primitive type), all the references will be null by default. These null
- references can result in NullPointerExceptions if you try to
- dereference them.
- In other words, after doing:
-
- int arr[] = new int[4];
-
-
- you can say
-
- if (arr[2] == 0)
-
-
- But after doing
-
- Integer Iarr[] = new Integer[4];
-
-
- you must fill in the object reference before using it. E.g.,
-
- Iarr[2] = myInt;
-
-
- or
-
- arr[2] = new Int(27);
-
-
- before you can say
-
- if (Iarr[2].equals(myInt))
-
-
- 24. (Sect. 6) How do I copy an array?
-
- [*] If the array only contains primitive types or if you want to copy
- only the object references, not duplicate the objects, then use the
- method
-
- java.lang.System.arraycopy(Object src, int src_position,
- Object dst, int dst_position, int length);
-
-
- Otherwise, if you want to duplicate the objects, you have to initialize
- your new array and write a loop that duplicates each object in the old
- array into the new.
-
- Note that the documentation for arraycopy() says that if src and dst
- refer to the same object, then arraycopy behaves as if the source array
- elements are copied into a temporary array (i.e., they are preserved).
- Some interpret this as meaning a temporary array will be so allocated,
- but that's not Sun's implementation.
-
- Other sites:
- JLS 20.18.16 {java.lang.System.arraycopy()}
-
- 25. (Sect. 6) How do I clear an array?
-
- [*] There is no method to clear an array to 0.0, 0, null, false,
- '\u0000' etc. When you allocate an array, the elements are set to their
- default values, but that doesn't help when you want to reuse an array.
-
- If you want to set the same array to the same set of values many times,
- create a template array. Fill it with the reset value, then use
- System.arraycopy() to copy it into the work array each time you need to
- set the work array.
-
- 26. (Sect. 6) What is a fast way to set all elements of an array?
- I don't want to use a template array. I would like to set all array
- elements to a given value without duplicating the (possibly large)
- array.
-
- [*] Using a loop that does it one by one is probably 20 to 40 times
- slower than good old memset() in C.
-
- A fast way on many VM's is to set the first byte of the array, then use
- System.arraycopy() repeatedly to fill the next byte, the next two
- bytes, the next four bytes, the next eight bytes, etc., and when you
- get past halfway, fill in the rest.
-
- public static void bytefill(byte[] array, byte value) {
- int len = array.length;
- if (len > 0)
- array[0] = value;
- for (int i = 1; i < len; i += i)
- System.arraycopy( array, 0, array, i,
- ((len - i) < i) ? (len - i) : i);
- }
-
-
- This is faster on Sun's VM than a simple loop, and probably even faster
- under JITs because it only performs at most log2(array.length) bounds
- checks. This is a clever code idiom applying the binary chop algorithm
- to arrays even when their size is not a power of 2.
-
- -------------------------------
-
- 7. I/O
-
- 1. (Sect. 7) How do I read a String/int/boolean/etc from the keyboard?
-
- [*] The easiest way is to pick up the source for the 100% pure Java
- class EasyIn from http://www.afu.com/ (same place as this FAQ). Compile
- it with your code and use it like this:
-
- EasyIn easy = new EasyIn();
-
- int i = easy.readInt(); // gets an int from System.in
- boolean b = easy.readBoolean(); // gets a boolean from System.in
- double d = easy.readDouble(); // gets a double from System.in
-
-
- ... etc.
-
- EasyIn is free, comes with source, and you can do what you like with
- it, including improve it, and send me back the results.
-
- If, instead, you want to "roll your own" code (why?!), in JDK 1.0.2
-
- java.io.DataInputStream in = new java.io.DataInputStream(System.in);
- String s = in.readLine();
-
-
- One way in JDK 1.1:
-
- java.io.BufferedReader in =
- new java.io.BufferedReader( new InputStreamReader(System.in));
-
- String s = in.readLine();
-
-
- Once you have the token in a String, it is easy to parse it into one of
- the other types, as shown earlier in the FAQ. Yes, it is bone-headed,
- as it makes the simplest case of keyboard I/O unnecessarily
- complicated. A bug was filed with Javasoft to record this problem, but
- don't count on this being fixed any time soon.
-
- 2. (Sect. 7) Why do I have trouble with System.out.println()? Check the
- spelling. The last two characters are the letters "ell enn" not "one
- enn".
-
- The name of the method stands for "print line", since it prints a
- String and goes to the next line, rather than staying on the same line
- as System.out.print() does. Yes, the name is yet another Java naming
- inconsistency, since the input equivalent is readLine(), not readln().
-
- 3. (Sect. 7) How do I write to the serial port on my PC using Java?
-
- [*] There is a platform-independent serial port API introduced in JDK
- 1.2. You can download the documentation by registering with the Java
- Developer Connection (it's free, http://java.sun.com) and browsing
- http://java.sun.com/jdc/earlyAccess/communications.html.
-
- For systems prior to JDK 1.2, read on. At least two companies have
- written a library to drive the port. See
- o http://www.sc-systems.com has a library for Windows 95, WindowsNT,
- OS/2, Macintosh PPC, Solaris Sparc, Linux x86, FreeBSD x86, HP/UX
- PA-RISC, and possibly others too.
- o http://www.cd.com/portio
- o In addition, there is a Unix serial port utility available with
- source at http://jarvi.ezlink.com/rxtx/ It's free under the GPL,
- and works on Linux, Irix, Solaris, Windows 95, and NT.
-
- While not helpful to typical home users, there is an alternative
- portable COM port solution for Java 1.1 and even 1.0. Buy your COM
- ports in the form of "terminal servers". Using a COM port is now as
- easy as connecting to it with a Socket. Port parameters can be changed
- programatically using SNMP for most terminal servers (but this is never
- necessary when a modern modem or other fixed-rate equipment is
- attached). Any networked box can serve as a terminal server - even
- Win95 - with a simple native server application for that box, but
- buying an actual firmware based hardware box is much easier.
-
- Furthermore, your Win95 native applications can now share the COM ports
- (and any attached modems) via a Win95 product called "Dial-out IP" at
- http://www.tactical-sw.com/.
-
- If the port exists as a pathname in the filesystem, you can open it as
- a file and read/write. You can also print text this way by writing to
- "prn" or "lpt1" on a pc, and "/dev/something" on Unix. Writing a
- formfeed at the end of the file is essential on Windows 95. Here is
- some sample code:
-
- // class that opens the printer as a file
- // and writes "Hello World" to it
-
- import java.io.*;
- public class lpt {
- public static void main (String[] argv) {
- try {
- FileOutputStream os = new FileOutputStream("LPT1");
- //wrap stream in "friendly" PrintStream
- PrintStream ps = new PrintStream(os);
-
- //print text here
- ps.println("Hello world!");
-
- //form feed -- this is important
- //Without the form feed, the text will simply sit
- // in print buffer until something else gets printed.
- ps.print("\f");
- //flush buffer and close
- ps.close();
- } catch (Exception e) {
- System.out.println("Exception occurred: " + e);
- }
- }
- }
-
-
- If you wish to change the characteristics of the port (e.g. baud rate,
- parity, etc.), not just read/write data, Java currently offers no
- portable way to do this. You will need to use one of the packages
- mentioned above or some native code or a system command.
-
- 4. (Sect. 7) How do I append to a file?
-
- [*] There are two ways. JDK 1.1 introduced new constructors for two of
- the output classes that allowed you to set a boolean flag:
-
- public FileWriter(String fileName, boolean append) throws IOException
- public FileOutputStream(String name, boolean append) throws IOException
-
-
- Another way is to do this:
-
- RandomAccessFile fd = new RandomAccessFile(file,"rw");
- fd.seek(fd.length());
-
-
- Then write using fd. Note that the latter method does not take
- advantage of the "append" mode present in many operating systems (such
- as all Unixes). Such a difference may make a difference with multiple
- processes or threads appending to the same output file. This can happen
- frequently, even if not intended by the programmer, e.g. with logfiles
- in multitasking environments. With the lack of file-locking mechanisms
- in Java the issue becomes even more significant.
-
- 5. (Sect. 7) Is it possible to lock a file using Java ?
-
- [*] Java does not feature an API to lock a file or regions within a
- file. Code that needs to do this must take one of four approaches:
- 1. Implement an advisory locking scheme using features that Java does
- have (synchronized methods). This allows you to lock files against
- use by other Java code running in the same JVM.
-
- 2. Use an atomic operation like file "renameTo()" and have all
- processes (Java and non-Java) follow the same protocol: if the
- operation succeeds, you have the lock, and you change the file
- back to give up the lock. The FAQ previously recommended delete()
- or mkdir() as the primitive, but there has been a report that
- these operations are idempotent (can be repeated without error) in
- some JVMs. The suggestion of renameTo has been proven to work in
- practice. See http://www.camb.opengroup.org/~sanfilip/FileLock/
- for example locking class docs and source.
-
- 3. Make calls to native code to issue the locking ioctls. This
- approach is not portable, but gives you a shot at having your
- locks respected by other programs using standard locking ioctls
- outside Java.
-
- 4. Push the work to a central server. Since socket connection
- requests arrive in a single queue on the server, this can be used
- to serialize lock requests. There might be some merit in copying
- the NFS lockd protocol for a general approach. Rolling your own
- simple version for a specific application is pretty easy. A
- database would be better off locking records or fields, not byte
- offsets. In theory, the server socket approach would make it
- easier to perform automatic cleanup of a lock on abrupt VM process
- failure, e.g. by asking "are you still alive?" to the lock holder
- occasionally.
-
- 6. (Sect. 7) How do I make the keyboard beep in Java?
-
- [*] In JDK 1.1, java.awt.Toolkit has the method beep(). It does not
- work on NT 4.0 (bug).
-
- System.out.print("\07");
- System.out.flush();
-
- should work, and works in JDK 1.0.2, too. That's the ASCII BEL
- character (Java doesn't support the C abstraction of '\a' for an alert
- character).
-
- 7. (Sect. 7) How do I execute a command from Java? How do I do I/O
- redirection in Java using exec()?
-
- [*] See the answer to Question 17.7.
-
- 8. (Sect. 7) How do you do file I/O from an applet?
-
- [*] For security reasons, untrusted applets accessed across the network
- are restricted from doing certain operations, including I/O. This
- prevents rogue applets from sending out your private data, or deleting
- it. A trusted (signed) applet can perform these operations (JDK 1.1
- on).
-
- The simplest approach for server-side I/O is to use the Linlyn class
- available from http://www.afu.com. This is free software under the GNU
- license, and uses FTP to move files between an applet and the server.
- It is suitable for low-volume non-critical use like keeping a
- high-score file. The Linlyn class has a very simple application
- programmer interface.
-
- o The following suggestion is for server-side input.
-
- You can read a file on the server if you can create a URL
- referencing the file. Then open a stream, then use any of the
- stream-based methods to read.
-
- This allows reading but not writing. It requires an http daemon
- running on the server, which will usually be the case.
-
- try{
- URL url = new URL("http://somewhere.com/test.txt");
- // or URL url = new URL( getDocumentBase(), filename);
- BufferedReader in = new BufferedReader(
- new InputStreamReader(
- url.openStream() ) );
- String s = in.readLine(); //read till you get a null line.
- } catch(MalformedURLException e){
- System.out.println("URLException:"+e);
- } catch(IOException e){
- System.out.println("IOException:"+e);
- }
- }
-
-
- You cannot write a file on the server this way.
- o The following suggestions are for server-side output.
-
- It absolutely requires the cooperation of the server to allow an
- applet to write a file to the server. This cooperation may take
- any of several forms:
- + FTP server
- + File server (webnfs or custom written)
- + Listening on a socket for data from applets
- + CGI script
- + Java RMI (remote method invocation)
- + JDBC process
-
- In particular:
- + FTP code. Use the Linlyn class mentioned above.
- + WebNFS. This is an evolution of the NFS (Network File System)
- to make file resources visible in browsers. More information
- at http://www.sun.com/webnfs
- + Open a socket back to the server and read/write the data.
- Have a process on the server that listens for socket
- connections from applets and does the requisite I/O. This
- does I/O on the server.
- + Or use a CGI script or servlet on the server to write when
- browsed.
- o The following suggestions are for client-side I/O.
-
- Use a trusted applet (see section on security). This will permit
- local I/O without any of the restraints mentioned above. In this
- regard, the appletviewer and many other browsers regard applets
- loaded from a local filesystem (rather than across the net) as
- being more trustworthy, and perhaps even allowed to do I/O.
- o Or use a browser that has a security policy that is configured to
- allow file I/O (such as Sun's appletviewer).
-
- 9. (Sect. 7) I used a C program to write a binary file. When I instantiate
- a DataInputStream on the file in Java, and try to readInt, I do not get
- the correct numbers. Why is this?
-
- [*] Java does everything in network byte order (big-endian order), as
- do many computers including Motorola, and SPARC. The Intel x86 uses
- little-endian order in which the 4 bytes of an int are stored least
- significant first. Rearranging the bytes on the way in will get you the
- results you need. This is only necessary when the file was written by a
- non-Java program on a little-endian machine such as a PC.
-
- The following code will byte-swap little-endian integers into network
- standard order:
-
- public int swap(int i) {
- int byte0 = i & 0xff;
- int byte1 = (i>>8) & 0xff;
- int byte2 = (i>>16) & 0xff;
- int byte3 = (i>>24) & 0xff;
- // swap the byte order
- return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
- }
-
-
- Alternatively, the following code assembles bytes from a byte array
- that is in big-endian order (as used by Java) into an int:
-
- byte[] bytes = ... // whatever
- int start_index = ... // wherever
-
- int value = 0;
- for ( int i = start_index; i < start_index+4; ++i ) {
- value = ( value << 8 ) | ( bytes[i] & 0xFF );
- }
-
-
- If the bytes are in little-endian order, just change the "for"
-
- for ( int i = start_index+3; i >= start_index; --i )
-
-
- And this code will assemble a double that has been written in reverse
- byte order:
-
- byte[] gnol = new byte[8];
- stream.read(gnol);
-
- long l = (
- ( (gnol[7] & 0xff) << 56) |
- ( (gnol[6] & 0xff) << 48) |
- ( (gnol[5] & 0xff) << 40) |
- ( (gnol[4] & 0xff) << 32) |
- ( (gnol[3] & 0xff) << 24) |
- ( (gnol[2] & 0xff) << 16) |
- ( (gnol[1] & 0xff) << 8) |
- (gnol[0] & 0xff)
- );
-
- double d = Double.longBitsToDouble(l);
-
-
- 10. (Sect. 7) How do I make I/O faster? My file copy program is slow.
-
- [*] This is the purpose of BufferedInputStream. It is a flaw in Java
- that buffered I/O is not the default, with a flag or different
- constructor to turn it off. I/O is the second worst designed package in
- Java, after the Date class. ,
-
- 11. (Sect. 7) How do I do formatted I/O of floating point numbers?
-
- [*] Use the class java.text.NumberFormat.
-
- Or use http://www.newbie.net/sharky/lava/. Or do a web search for
- hbprintf. Or use http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html
- for the HTML with the javadoc info. The actual file is called
- http://www.apl.jhu.edu/~hall/java/CoreJava-Format.java. However, you
- must rename the file to Format.java for it to compile. Also, one
- version of this had a bug: When you try to format a true 0 you go into
- an infinite loop (need to test d in exp_format).
-
- Although many utilities claim to handle all varieties of C's printf, as
- far as has been found, this is the only one to correctly handle the
- equivalent of %e in printf.
-
- 12. (Sect. 7) How do I read numbers in exponential format in Java?
-
- [*] The program below (written by Steve Chapel) uses StreamTokenizer to
- read data from the standard input and recognizes doubles in exponential
- format (e.g. -1.23e-45).
-
- import java.io.*;
-
- public class ReadExponential {
- public static void main(String argv[]) {
- DataInputStream in = new DataInputStream(System.in);
- StreamTokenizer st = new StreamTokenizer(in);
- try {
- while (st.nextToken() != StreamTokenizer.TT_EOF) {
- switch (st.ttype) {
-
- case StreamTokenizer.TT_NUMBER:
- double num = st.nval;
- int exp = 0;
- st.ordinaryChars('\0', ' ');
- st.nextToken();
- st.whitespaceChars('\0', ' ');
- if (st.ttype == StreamTokenizer.TT_WORD &&
- Character.toUpperCase(st.sval.charAt(0)) == 'E') {
- try {
- exp = Integer.parseInt(st.sval.substring(1));
- } catch (NumberFormatException e) {
- st.pushBack();
- }
- } else if (st.ttype < 0 || st.ttype > ' ')
- st.pushBack();
- System.out.println("Num " + num * Math.pow(10, exp));
- break;
- case StreamTokenizer.TT_WORD:
- System.out.println("Word " + st.sval);
- break;
- default:
- System.out.println("Char '" + (char) st.ttype + "'");
- break;
- } // end switch
- } // end while
- } catch (IOException e) {
- System.out.println("IOException: " + e);
- }
- } // end main
- }
-
-
- 13. (Sect. 7) I'm trying to read in a character from a text file using the
- DataInputStream's readChar() method. However, when I print it out, I
- get ?'s.
-
- [*] Remember that Java characters are 16-bit Unicode characters, while
- many hosts systems store characters as 8-bit ASCII characters.
- Therefore, to read individual chacters from a text file, you need to
- ensure the proper conversion. The proper way to do this is to use an
- InputStreamReader, which converts from 8 to 16 bit streams:
-
- FileInputStream fis = new FileInputStream("myfile.txt");
- InputStreamReader isr = new InputStreamReader(fis);
- char c3 = (char) isr.read();
-
- The less-favored way (because it is not so portable, as the encodings
- translation is not done) is just to read a byte and cast it into a
- character:
-
- FileInputStream fis = new FileInputStream("myfile.txt");
- DataInputStream dis = new DataInputStream(fis);
- char c1 = (char) dis.readByte();
-
-
- 14. (Sect. 7) How do I delete a directory in Java?
-
- [*] JDK 1.0 did not support directory removal. JDK 1.1 supports
- directory removal with the method:
- public boolean delete() in class java.io.File
-
- Make sure you don't have any open streams in the directory you're
- trying to remove. Do a close() on all streams, even if the underlying
- file is gone.
-
- 15. (Sect. 7) How do I tell how much disk space is free in Java?
-
- [*] There currently aren't any good Java APIs for system introspection.
- There is no Java way to control processes, or look at system resources.
- You can use Runtime.getRuntime().exec() to do "df" on unix or "dir" on
- Windows right now.
-
- Alternatively, check out JConfig:
- http://www.tolstoy.com/samizdat/jconfig.html
- JConfig is a cross-platform library that fills in many of the gaps in
- the core Java API, and makes it possible to work with files, processes,
- file types, video monitors, etc. in a much more Windows- and
- Mac-friendly manner.
-
- 16. (Sect. 7) How do I get a directory listing of the root directory C:\ on
- a PC?
-
- [*] The obvious approach of calling File.list("C:\"); does not work.
- There are two reasons why this fails. First, slash is an escape
- character in Java, so if you want a literal slash, you have to repeat
- it. Second, you need to give the name of the directory, i.e. dot.
- Putting this together, either of the following calls will work
-
- File.list("C:\\.");
-
-
- or
-
- File.list("C:/.");
-
-
- Note: a file separator of "/" works just as well as "\" in most Windows
- programs and library calls. It is an artifact of DOS's origin's as a
- ripped-off port of CP/M. CP/M didn't have directories, so it didn't use
- pathname separators. The forward slash "/" was already used for giving
- options to CP/M commands, so "\" was pressed into service as the
- pathname separator, but the shell understood "/" for compatibility with
- other OS's. See also JConfig in Q6.15.
-
- 17. (Sect. 7) What is the difference between the various ZIP formats: ZIP,
- GZIP, and PKZIP?
-
- [*] Zip is an archive file format, popularized on PCs, that contains
- multiple compressed files.
- GZIP comes from Gnu. It is essentially a one file subset of the Zip
- format. You can't put a whole directory into a GZIP archive, just a
- single file.
- PKZIP is a set of commercially available programs that create Zip
- files. All three use the deflate compression format, which is based on
- the LZ77 algorithm. This compression is also used by the ZLIB library
- and hence the PNG graphics file format (which uses ZLIB). PNG -
- Portable Network Graphics - provides a patent-free replacement for GIF
- and TIFF. If you save a GIF, don't forget to pay the royalty to Unisys
- - see Unisys's web page at http://www.unisys.com/LeadStory/lzwfaq.html.
- That patent is why GIFs should not be used.
-
- The PNG format is specified in RFCs 1950, 1951, and 1952, and is
- unencumbered by licenses or patents.
-
- An alternative compression technology, LZW compression, is encumbered
- by Unisys's patent. LZW is used in GIF files and by the Unix compress
- command. Luckily, as well as being free from patent restrictions, LZ77
- also gives better compression than LZW. LZW is the initial letters of
- the last names of the three computer scientists who developed the
- algorithm (Lempel, Ziv, Welch).
-
- The basic classes (all in java.util.zip) that read LZ77 Zip format are
- Deflater and Inflater. These are used by the stream classes
- DeflaterOutputStream and InflaterInputStream. The java.util.zip classes
- GZIPInputStream and ZipInputStream inherit from InflaterInputStream.
-
- PKZIP is a commercial program for DOS, Windows, and OS/2, sold by
- PKWARE Their FAQ, at http://www.pkware.com/zipgfaq.html, specifically
- says
- "Because PKWARE has dedicated the .ZIP file format to the public
- domain, it is possible for other people to write programs which
- can read .ZIP files. NOTE THAT THE PKZIP, PKUNZIP, PKSFX PROGRAMS
- AND THEIR ASSOCIATED SOURCE CODE AND SUPPORT PROGRAMS ARE THE
- EXCLUSIVE PROPERTY OF PKWARE INC. AND ARE NOT PUBLIC DOMAIN
- SOFTWARE PROGRAMS.
-
- The "other people" PKZIP's FAQ refers to is the InfoZIP project, a
- group of public-minded programmers spread over the world producing free
- software that works on most ANSI C compilers and platforms. See
- http://www.cdrom.com/pub/infozip/.
-
- Jar files are in ZIP format, but are not as complete as a full
- filesystem archive format since file permissions are not saved. Some
- versions of WinZip are known to be inadequate for processing the full
- PKZIP format. Use InfoZIP instead.
-
- 18. (Sect. 7) How can I use characters other than ASCII in Java?
-
- [*] Search for the article titled "Adding Fonts to the Java Runtime" at
- http://java.sun.com/.
-
- The article explains how to add fonts to Sun's JDK, using the
- font.properties file. [If anyone has summarised the information, please
- send it in].
-
- 19. (Sect. 7) I did a read from a Buffered stream, and I got fewer bytes
- than I specified.
-
- [*] This is the way that BufferedInputStream works up to and including
- the current release. The behavior is so unintuitive that it really
- represents a bug. Javasoft has "resolved" the bug by writing the
- comments in the program so that the behavior is not disallowed.
-
- When you instantiate a buffered input stream, you can specify the size
- of buffer it should use. Let's call this the internal buffer. When you
- call read() you can say how many bytes to read. Let's call this the
- request. If the request is smaller than the internal buffer and not a
- multiple of the internal buffer, then the last read returns only the
- odd bytes left in the internal buffer! The more reasonable and
- intuitive behavior would be for the internal buffer to be refilled, so
- that the whole request can be granted.
-
- For example, if you create a BufferedInputStream with an internal
- buffer of 1000 bytes, and try to read 512 byte chunks, your first read
- will return 512 bytes, but your second read will only return
- (1000-512), or 488, bytes. (Assuming that the file has at least that
- many bytes in it). The following code illustrates the problem.
-
- // troubleshooting by Tov Are Jacobsen
- import java.io.*;
- class filebug {
- public static void main(String args[])
- throws FileNotFoundException, IOException {
- BufferedInputStream bis =
- new BufferedInputStream(
- new FileInputStream("test.txt"), 1000 );
- byte[] buf = new byte[2000];
- int numread;
- System.out.println( "Available: "+bis.available() );
- while (true) {
- numread = bis.read(buf,0,512);
- if (numread<0) break;
- System.out.println( "got "+numread
- +", avail:"+ bis.available());
- }
- }
- }
-
-
- Of course, a valid reason for getting less than you asked for is that
- you asked for more data than is actually available in the Stream, e.g.
- you requested 512 bytes from a file that only contains 40 bytes. In
- general, there are no guarantees about how much data is returned for a
- given buffered input stream read request. To avoid this problem, push a
- DataInputStream on top of your buffered stream. Then you can call
- readFully(), which will do what you want.
-
- A similar "got less than I asked for" occurs when reading a socket.
- Network protocols frequently packetize data and send it across in
- bursts. Nothing is lost of course, and you are always told how many
- bytes you actually got. You will get the remaining bytes on a
- subsequent read. This happens regardless of the language used. Be sure
- to check the "amount of data returned" when using the read(byte[], int,
- int) method of BufferedInputStream, or when reading from a socket.
-
- Another problem with java.io.InputStream.read(byte[], int, int) is that
- it catches and ignores IOExceptions. Instead, these exceptions should
- be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com,
- has a version to do this at http://www.acme.com/jef/.
-
- 20. (Sect. 7) How do I redirect the System.err stream to a file?
-
- [*] You cannot assign a new FileOutputStream to System.err, as it is
- final. Instead use the System.setErr() library call, like this:
-
- FileOutputStream err = new FileOutputStream("stderr.log");
- PrintStream errPrintStream = new PrintStream(err);
- System.setErr(errPrintStream);
-
-
- This was introduced with JDK 1.1. There is also a corresponding setIn()
- for redirecting standard in, and a setOut() for standard out.
-
- Note that you will get a compiler warning about a deprecated construct
- when you do this. PrintStreams are deprecated in favor of PrintWriters,
- which handle Unicode properly. The PrintStream is marked as deprecated
- by marking all its constructors as deprecated. There is no way to
- create the PrintStream needed to redirect System.err or System.out
- without triggering the deprecated warning.
-
- -------------------------------
-
- 8. Core Libraries
-
- 1. (Sect. 8) I can't seem to change the value of an Integer object once
- created.
-
- [*] Correct. Integer (Float, Double, etc) are intended as an object
- wrapper for a specific value of a number, not as a general-purpose way
- of shipping a primitive variable around as an Object. If you need that
- it's easy enough to create: class General { public int i; }
-
- 2. (Sect. 8) How do I print from a Java program?
-
- [*] Use the Toolkit.getPrintJob() method
-
- Component c = this.getParent();
- while (c!=null && !(c instanceof Frame))
- c=c.getParent();
-
- PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
- Graphics pg = pj.getGraphics();
- printAll(pg);
- pg.dispose();
- pj.end();
-
-
- This feature was introduced with JDK 1.1. A common place to put this is
- in the code that handles a button press. Printing from an untrusted
- applet is subject to a check from the SecurityManager.
-
- The JDK 1.1 printing API is more a screen hardcopy facility than a full
- blown publishing and illustration hardcopy API. JDK 1.2 offers a more
- full-featured printing API.
-
- If you simply want to print text, then write it to a file and print the
- file. Or open a filename that corresponds to the printer. On Windows,
- that is "LPT1" and the code looks like:
-
- try {
- FileOutputStream fos = new FileOutputStream("LPT1");
- PrintStream ps = new PrintStream(fos);
- ps.print("Your string goes here");
- ps.print("\f");
- ps.close();
- } catch (Exception e) {
- System.out.println("Exception occurred: " + e);
- }
-
-
- The final formfeed is needed by windows to start the printjob.
-
- 3. (Sect. 8) What are the properties that can be used in a PrintJob?
-
- [*] The properties are
- o awt.print.destination - can be "printer" or "file"
- o awt.print.printer - printer name
- o awt.print.fileName - name of the file to print
- o awt.print.options - options to pass to the print command
- o awt.print.orientation - can be "portrait" or "landscape"
- o awt.print.paperSize - can be "letter","legal","executive" or "a4"
- The defaults are destination=printer, orientation=portrait,
- paperSize=letter, and numCopies=1.
-
- You can search for info like this by joining the Java Developer
- Connection (it's free) at http://java.sun.com/jdc.
-
- and doing a search for "PrintJob".
-
- 4. (Sect. 8) Is there any package in Java to handle HTML?
-
- [*] See the answer to Question 13.14.
-
- 5. (Sect. 8) Why don't Dialogs work the way I want them to?
-
- [*] Modal dialogs (dialog windows that stay up until you click on them)
- are buggy in many browsers and in the 1.0.2 JDK. One bug is that the
- dialog is not necessarily put on top when it is displayed. Most of the
- modal dialog bugs are fixed in JDK 1.1.
-
- 6. (Sect. 8) Where can I find information about the sun.* classes in the
- JDK?
-
- [*] You're not supposed to. Those classes are only to support functions
- in the java.* hierarchy. They are not part of the API, and won't be
- present in Java systems from non-Sun vendors. Some people have
- reverse-engineered the code and published an API for these classes but
- you use it at your own risk, and it may change without warning.
-
- Worst of all, those programs will not have the portability of true Java
- but will only run on Sun JDKs. For the same reason you shouldn't use
- classes outside the java.* packages when using JDKs from other vendors.
-
- If you still insist on going ahead, check these URLs:
- http://java.sun.com/products/api-overview/index.html
- http://www.parmly.luc.edu/javaudio/
- http://www.users.interport.net/~mash/javamidi.html
-
- 7. (Sect. 8) How do you read environment variables from with a Java
- program?
-
- [*] Environment variables are not used in Java, as they are not
- platform-portable. The Mac doesn't have environment variables, for
- example. A Windows 95 application not started from a DOS window does
- not have environment variables. Use properties instead. It was a design
- error in JDK 1.0 that programmers had to set the CLASSPATH environment
- variable. This should have been set in a property file. JDK 1.1 removes
- the need to set the CLASSPATH environment variable until you start
- creating packages of your own.
-
- Create your own properties file (see java.util.Properties) or specify
- them with the -D option when you invoke the interpreter or JRE.
- Additionally, on some systems you can set a property from the command
- invocation line like this:
-
- java -Dfoo=$foo MyClass (Unix)
-
- or
-
- java -Dfoo=%foo% MyClass (Win95/NT)
-
- This sets the "foo" property to the value of the environment variable
- foo, and makes it available in the System properties. Make sure you do
- not leave any spaces after the -D or around the = sign. Inside the
- program you get the value with:
-
- String env = System.getProperty("foo");
-
- More simply, just put the environment variable on the command line and
- read it as arg[0].
-
- java MyClass %FOO% ; Win32
- java MyClass $FOO ; Unix
-
-
- Finally, you could execute a Runtime process to get the environment
- variables if you are on a platform that has them. This is a poor
- approach as it builds platform-specific knowledge into the program. See
- Question 10.6 for more details. On Unix, the command that prints
- environment variables is "/usr/bin/env". On Windows95, it is "set"
-
- 8. (Sect. 8) How do I get Java talking to a Microsoft Access database?
-
- [*] Use the JDBC-ODBC bridge. It is not especially challenging to set
- up, but it does require painstaking attention to detail. There is a
- step-by-step example in the van der Linden text "Just Java 1.1"
- mentioned in the ponsorship section of this document.
-
- Note that the Microsoft version of the Java kit does not support
- JDBC-ODBC access because it uses a non-standard native code interface.
- The JDBC FAQ can be found at
- http://java.sun.com/products/jdbc/jdbc-frequent.html
-
- 9. (Sect. 8) I can't seem to change the current working directory.
-
- [*] Correct. This missing functionality is an oversight that we hope
- will be corrected in the future. The bug id is 4156278, please feel
- free to join the JDC, and vote to have this (or any other) fixed.
- Changing the user.dir property merely changes the text property, not
- the underlying reality that it is supposed to reflect.
-
- There are several workarounds.
- o Run your java app from a .bat or .sh file and do the "cd" in that
- (before you run your java app), assuming that all the external
- processes you need to exec can be run from the same directory.
- o Do: exec("cd /home/wherever; externalApp.exe") on unix, (there
- doesn't seem to be an equivalent on NT).
- o Instead of running the .exe directly, run (or write on the fly) a
- .bat or .sh file that does the cd and then runs the .exe for you
- (this could well create trouble with getting back the correct
- return status)
-
- 10. (Sect. 8) How do I create a Vector of ints?
-
- [*] ints are primitive types and hence can't be stored by the Vector
- class, which stores objects. You'll need to wrap the ints. Try this:
-
- int i =7;
- Vector holdsInts = new Vector(5,1);
-
- holdsInts.addElement(new Integer(i));
- int j = ((Integer)holdsInts.elementAt(0)).intValue();
-
-
- 11. (Sect. 8) I have several worker threads. I want my main thread to wait
- for any of them to complete, and take action as soon as any of them
- completes. I don't know which will complete soonest, so I can't just
- call Thread.join on that one. How do I do it?
-
- [*] You need to use the wait/notify mechanism to allow any of the
- worker threads to wake up your main thread when the worker has
- completed.
-
- 12. (Sect. 8) How do I get random numbers?
-
- [*] If you just need a quick random double between 0.0 and just less
- than 1.0
-
- double myrandom = Math.random(); // [0,1)
-
-
- The notation "[0,1)" is common math notation for "zero to .9999999 etc"
- The Sun documents say this returns 0.0 to 1.0, but inspection of the
- source shows they are wrong. However, due to the inherent inaccuracies
- of floating point arithmetic, multiplying N by 0.999999 etc can result
- in an answer of N, not N * .999999. So watch out when N is big.
-
- Where things get even trickier is in the case where you want an int
- within a certain range, say 1 to 6 to simulate the throw of a die or 1
- to 52 to represent a playing card. Class Random has a nextInt method
- that will return any integer:
-
- import java.util.Random;
- Random r = new Random();
- int i = r.nextInt();
-
-
- However, that has an (almost) 50% chance of being negative, and it
- doesn't come from the right range. So you just take the abs() value and
- then mod it into the right range:
-
- int dice_throw = 1 + Math.abs(i) % 6;
-
-
- Except, the abs() method fails gracelessly in the presence of the
- Integer.MIN_VALUE (it returns the same, negative, result!). So it is
- better to AND to get the non-negative value: In general, to get a
- random int between high and low limits (inclusive):
-
- java.util.Random r = new java.util.Random();
- int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;
-
-
- The sentence above states "(almost) 50% chance" because there is one
- more value in the negative integers than in the positive integers in
- two's complement arithmetic as used by Java. For most purposes, the
- bias introduced will be insignificant, but we "and" the nextInt() to
- convert it to zero. Sure, it's unlikely to occur, but you don't want
- the reactor going critical just because you missed this case while
- testing.
-
- A worse problem is that with the algorithm used, the low order bits are
- significantly less random than the higher order bits. And the low order
- bits are precisely the ones you get when you do a (mod 2^n) operation.
-
- 13. (Sect. 8) What does "deprecated" mean? I got this in a compiler error
- message.
-
- [*] The compiler will flag a now-obsolete API as "deprecated". The word
- means "officially disapproved of". Compile again with the
- "-deprecation" option to see what is deprecated. In almost all cases,
- the old API has been replaced by a new one. Update your code to use the
- new one.
-
- An example of using a deprecated API is calling component.size(). That
- has been replaced by component.getSize().
-
- 14. (Sect. 8) Where/why should I use the Enumeration interface?
-
- [*] It's a very convenient way to step through some of the library data
- structures, such as HashTable, Vector, and ZipFile. It is thread safe.
- If you're looking at an element in one thread while another thread is
- trying to delete it, it won't half vanish.
-
- Here's how you might look at every file in a ZIP file:
-
- ZipFile z = new ZipFile("foo.zip");
- Enumeration e = null;
- for (e=z.entries(); e.hasMoreElements(); ) {
- ZipEntry ze = (ZipEntry)e.nextElement();
- System.out.println("got " + ze.getName() );
- }
-
-
- And here's how you might look at all the tokens in a String:
-
- StringTokenizer tokens =
- new StringTokenizer (SomeArbitraryString, "\n", false);
-
- Enumeration enum = tokens.elements();
- while enum.hasMoreElements()
- System.out.println(enum.nextElement());
-
- You should look for opportunities in your own data structures to
- implement Enumeration anywhere where the structure has repeated
- elements.
-
- 15. (Sect. 8) Which version of WinZip is compatible with java.util.zip?
-
- [*] You need WinZip version 6.2 or later. Version 6.1 or earlier is not
- good enough. WinZip can be downloaded from
- http://www.winzip.com/download.cgi. The pkzip software works fine.
- Infozip is better than WinZip because it lacks the winzip "feature" of
- failing to recreate directories unless given a special option. Use
- Infozip.
-
- 16. (Sect. 8) How can Java access other fonts on my system?
-
- [*] You do it by editing the fontnames in the font.properties file in
- the lib directory of your JDK release. Watch out for program
- portability when you do this.
-
- For more details, check the website
- http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft site
- at http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
- They have lots of information on this.
-
- 17. (Sect. 8) How can I trap Control-C in Java?
-
- [*] Control-C is used on some OS's to break into a running program
- interactively and terminate it. On Unix Control-C is sent to the
- process as a signal. If a C program declares a handler for that signal,
- the program will be able to continue even if Control-C is sent to it.
- Control-C is not a Java concept, and there is no way to do this in pure
- Java. You can write the signal handler in C however, and impose the
- handler by calling the C routine through the Java Native Interface.
-
- -------------------------------
-
- 9. Dates and Times
-
- Credit to Paul Hill who completely rewrote this section, and to
- the programmers at IBM who implemented much of the Java Date code,
- and reviewed this section of the FAQ for accuracy.
-
- java.util.Date
-
- 1. (Sect. 9) Is Java "Year 2000"-compliant?
-
- [*] Java is Y2K compliant in release JDK 1.1.6 and later. See
- http://www.sun.com/y2000/cpl.html. Prior to this release there were
- certain corner case bugs that had to be fixed.
-
- The Date class, as you can see from the discussion, contains more than
- enough resolution to represent dates in this century and the next and
- the last. The SimpleDateFormat when parsing a 2 digit year could cause
- problems; see discussion below.
-
- 2. (Sect. 9) What happen to java.util.Date between JDK 1.0 and JDK 1.1?
-
- [*] In JDK 1.1 the java.util.Date class was split to provide better
- support for timezones, and internationalization.
-
- The classes specifially related to dates are summarized below:
-
- 1. The class Date represents a specific instant in time,
- with millisecond precision.
- 2. The class TimeZone is an abstract class that represents
- a time zone offset, and also figures out daylight
- savings time adjustment.
- 3. The class SimpleTimeZone is the only concrete subclass
- of TimeZone in the JDK. It is what defines an ordinary
- timezone with a simple daylight savings and daylight
- savings time period.
- 4. The class Calendar is an abstract class for converting
- between a Date object and a set of integer fields such
- as year, month, day, and hour.
- 5. The class GregorianCalendar is the only concrete
- subclass of Calendar in the JDK. It does the
- Date-to-fields conversions for the calendar system in
- common use.
- 6. The class DateFormat is an abstract class that lets you
- convert a Date to a printable string with fields in the
- way you want (e.g. dd/mm/yy or dd.MMM.yyyy).
- 7. The class SimpleDateFormat is the only concrete subclass
- of DateFormat in the JDK. It takes a format string and
- either parses a string to produce a date or takes a
- date and produces a string.
-
- At least one critic has used the term "baroque" when describing the
- complexities of the Java date related classes, but other critics would
- spell that "broke". The good news is that as of JDK 1.2 all of the
- common problems have been corrected and many of the bugs were corrected
- in 1.1.4 and 1.1.6. Even in 1.1.1, you can avoid most of the most
- annoying bugs by always keeping in mind which timezone each class is
- using.
-
- 3. (Sect. 9) Exactly what is a java.util.Date?
-
- [*] A java.util.Date stores a moment in time as a long integer
- representing the number of milliseconds since 00:00:00 Jan 1, 1970 UTC
- (Coordinated Universal Time). This zero moment is known as the "Epoch".
- This is the same Epoch as is used on Unix systems. Dates earlier than
- the Epoch are represented as negative numbers, counting away from
- 1/1/1970.
-
- The scheme is sufficient to represent dates from 292,269,053 B.C. to
- 292,272,993 A.D. (64 bits covers -9,223,372,036,854,775,808 to
- +9,223,372,036,854,775,807 milliseconds. But note that prior to JDK
- 1.2, a GregorianCalendar will not accept values earlier than 4716 B.C.
-
- A java.util.Date is the light-weight object intended to just hold a
- millisecond value. It is used to hold, communicate and store a moment
- in time. Other tasks like creating a formated string, or calculating
- dates are best done using other classes.
-
- 4. (Sect. 9) Does a java.util.Date really represent the true UTC?
-
- [*] No, but it is close enough for most human time-keeping purposes. On
- most computers, it only represents the time since the epoch as
- converted from the value on the underlying hardware. If you have
- hardware that is synchronized with an atomic clock your time is UTC;
- most hardware assumes a day is 24 hours long, but there have been more
- than 20 leap seconds added to UTC, since the first one was added in
- 1972.
-
- 5. (Sect. 9) How do I create a Date object that represents the current
- time?
-
- [*] The default value of a date object is the current time, so the
- following code creates a date object that contains the current time.
-
- Date now = new Date();
-
- 6. (Sect. 9) I want to create a string that represents a date in a format
- other than what is returned by java.util.Date.toString() do I have to
- use a Calendar?
-
- [*] No. Instead of creating a Calendar and pulling out all of the
- appropriate fields and making a string, you could use
- SimpleDateFormat.format() to create a string.
-
- 7. (Sect. 9) Why are all the methods in java.util.Date deprecated?
-
- [*] Mostly because the original java.util.Date was not completely aware
- of the timezone and "not amenable to internationalization". To make it
- timezone aware and internationalizable would have required adding some
- of the functionality which can now be seen in java.util.Calendar and
- some of the functionality in java.util.DateFormat. If you find the
- combination all of the date related classes complex, just be glad they
- were separated into different classes.
-
- 8. (Sect. 9) I really don't need a internationalizable, timezone aware,
- extra flexible formating set of date classes, is there anything else
- with which I can use that stores a time and allows me to do some date
- calculations?
-
- [*]You could consider using the BigDate class written by Roedy Green,
- and available in his very informative glossary (search for BigDate). If
- you want to store the result in a database as a Date or TimeStamp, you
- should read the section below on java.sql.Date.
-
- 9. (Sect. 9) Since the Date( String ) constructor is deprecated what do I
- use instead?
-
- [*] The best choice is to use SimpleDateFormat.parse() to create a
- java.util.Date object.
-
- The Date constructor that accepts a string calls Date.parse( String ).
- The Date.parse() function had its own rules for converting 2 digit
- years (it used a 1980 pivot date) and other limitiations which makes it
- of limited value. Other "features" of Date.parse() that are not
- supported in SimpleDate have not been missed by many developers.
-
- 10. (Sect. 9) Since Date(int year, int month, int date) and related
- constructors are deprecated what do I use instead?
-
- [*] The constructor GregorianCalendar(int year, int month, int date) is
- the newer replacement. Other choices are the Calendar.set( year, month,
- day ) method. Note that the year in the GregorianCalendar starts at 1
- A.D., not at 1901 like the old Date constructor.
-
-
- java.util.TimeZone
-
- 11. (Sect. 9) How can I see if my JVM is using the right timezone?
-
- [*] The following codes displays the ID of the current default
- timezone.
-
- System.out.println( TimeZone.getDefault().getID() );
-
- 12. (Sect. 9) The value of TimeZone.getDefault is not what I expected. What
- is the problem?
-
- [*] The value of the default timezone is based on the value of the
- system property "user.timezone". The JVM is supposed to set this
- value. In releases such as JDK 1.1 the value of user.timezone was often
- not set to anything, so TimeZone.getDefault() used its own built in
- "fallback" value (the default when there is no default value). In later
- JDK 1.1 releases and in JDK 1.2 the setting of the value of
- user.timezone is much better and the "fallback" value is now GMT
- (Greenwich Mean Time). Up until JDK 1.1.3, the fallback value was "PST"
- (North American Pacific Timezone).
-
- 13. (Sect. 9) Do all the standard objects use the same default timezone?
-
- [*] Not until JDK 1.2. In JDK 1.1, Date.toString() and Calendar used
- the value of TimeZone.getDefault() which could often be undefined (see
- the previous question). In JDK 1.1, The Calendar in a SimpleDateFormat
- was set to the 1st timezone resource for the locale (for the US this is
- PST).
-
- System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() );
- sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
- System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() );
- Calendar cal = Calendar.getInstance();
- System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() );
-
- When run on a system running JDK 1.1.6, NOT in the North American
- Pacific Time nor in the GMT timezone results in:
-
- Timezone default = GMT
- Date format TZ = PST
- Calendar TZ = GMT
-
- This example shows two bugs, the value of user.timezone is undefined,
- so its defaulting to GMT (see discussion of TimeZone.getDefault()) and
- it shows that the DateFormat depends on the 1st locale entry which in
- this case is PST.
-
- If you don't want the DateFormat to use the Locale timezone, see the
- code provided below.
-
- 14. (Sect. 9) If I explicitly set the default timezone, don't I need code
- to choose between (a) the daylight savings version or (b) the standard
- version of a timezone?
-
- [*] No. The ID that you use to select a timezone with
- TimeZone.getTimeZone refers to a predefined timezone that contains
- daylight savings information (when applicable). For example, the
- following code selects the timezone used in New York, USA.
-
- // Get the North American Eastern Time definition.
- TimeZone theTz = TimeZone.getTimeZone( "EST" );
- // get a really detailed date format and set it to the right timezone
- DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG,
- DateFormat.LONG );
- df.setTimeZone( theTz );
- // create a date in the locale's calendar, set its timezone and hour.
- Calendar day = Calendar.getInstance();
- day.setTimeZone( theTz );
- day.set( 1998, Calendar.FEBRUARY, 1 );
- day.set( Calendar.HOUR, 12 );
-
- // print that date/time and that date/time 150 full days of milliseconds later.
- System.out.println( df.format( day.getTime() ) );
- System.out.println( df.format(
- new Date( day.getTime().getTime() + // get the millis
- 150L*24*60*60*1000L ) ) ); // add exactly 150 days of millis
-
- Results in:
-
- February 1, 1998 12:00:00 PM EST
- July 1, 1998 1:00:00 PM EDT
-
- Notice that this example selected something refered to as "EST", but
- that this TimeZone was aware of the daylight savings time change and
- either printed as "EST" or "EDT".
-
- The confusion is reduced in JDK 1.2, you can use longer TimeZone IDs
- each maps to its own set of text resources. For example the following
- IDs are 5 hour West of GMT and have various DST rules:
- "America/Nassau", "America/Montreal", "America/Havana",
- "America/Port-au-Prince", "America/Grand_Turk", "America/New_York" and
- "EST".
-
- You can look at a list of other timezone names and offsets in the file
- $JAVAHOME/src/java/util/TimeZone.java
-
- 15. (Sect. 9) How do I create my own Time Zone to apply to dates?
-
- [*] You can create a TimeZone object with the GMT offset of your
- choice. The following code creates British Time, a timezone that was
- not defined in 1.1.
-
- britTime = new SimpleTimeZone(0*ONE_HOUR, "Europe/London" /*GMT/BST*/,
- Calendar.MARCH, -1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
- Calendar.OCTOBER,-1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
- 1*ONE_HOUR),
-
- TimeZone.setDefault( britTime );
-
- Or you can then apply that TimeZone to a particular Calendar object
- like so:
-
- Calendar myCal = Calendar.getInstance();
- myCal.setTimeZone( britTime );
-
- If you are running 1.2, You can choose this existing timezone as the
- default with the code:
-
- TimeZone.setDefault( TimeZone.getTimeZone( "Europe/London" ) );
-
- Note that BST is defined from JDK 1.1 and later, but it is Bangladesh
- Standard Time. For a longer example of creating and testing the British
- timezone, Tony Dahlman provides a nice example in his BSumTime.java
- code.
-
- 16. (Sect. 9) How do I create the BST timezone specifically?
-
- [*] You can create an arbitrary TimeZone object with the code below. In
- most or all other timezones, daylight savings time is handled
- automatically and internally. But GMT is the reference for all other
- timezones, and so does not have the summertime update applied
- automatically. The rules for BST can be found at
- http://www.ast.cam.ac.uk/pubinfo/leaflets/summer/summer.html
-
- Here is the code to create a British Summer Time timezone that is
- offset one hour from GMT between two dates:
-
- import java.util.*;
- import java.text.*;
- // create a BST timezone (code courtesy of Tony Dahlman).
-
- public static GregorianCalendar setBritSummTime(String zoneName){
- // Set up the default GMT0BST time zone
- SimpleTimeZone bst_tz =
- new SimpleTimeZone( 0, // no offset from GMT
- zoneName, // individualized tz id
- // last Sun Mar 1AM
- Calendar.MARCH,-1,Calendar.SUNDAY,1*60*60*1000,
- // last Sun Oct 2AM
- Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000
- );
- SimpleTimeZone.setDefault(bst_tz);
-
- // Apply TimeZone to create a Calendar object for UK locale
- return (new GregorianCalendar(bst_tz,Locale.UK) );
- }
-
-
- and here is how you would print out values using BST:
-
- // create a template for printing the date
- DateFormat df = DateFormat.getTimeInstance(
- DateFormat.LONG,Locale.UK);
-
- // tell the template to use BST tz.
- df.setTimeZone(TimeZone.getDefault());
- System.out.println("Using British Summer Time "
- +"the time is: "
- + df.format( BritishSummerTime.getTime() ) );
-
- // Now get and compare with current time in GMT
- df.setTimeZone(TimeZone.getTimeZone("GMT") );
- System.out.println("\nCurrent time in GMT is: "
- + df.format(BritishSummerTime.getTime() ) );
-
-
- In the winter, this BST zone is aligned with GMT; in the summer it is
- one hour later (4 a.m. GMT is 5 a.m. BST).
-
- You can look at a list of timezone names and offsets in the file
- $JAVAHOME/src/java/util/TimeZone.java
-
- java.util.Calendar and java.util.GregorianCalendar
-
- 17. (Sect. 9)How do I a create a specific date in the Gregorian Calendar?
-
- [*]If you have a Date use:
-
- myCal.setTime( myDate );
-
- If you have a set of integers representing the year, month and day of
- month use:
-
- Calendar myCal = Calendar.getInstance();
- myCal.set( 1998, Calendar.MARCH, 15 );
-
- Note: Months start with January = 0!
-
- 18. (Sect. 9) How do I use a GregorianCalendar to extract a few fields from
- a Date?
-
- [*]The following code shows how to get some fields from a Date.
-
- Calendar g = Calendar.getInstance();
- g.setTime( aDate );
- int year = g.get( Calendar.YEAR );
- int mon = g.get( Calendar.MONTH );
- int date = g.get( Calendar.DATE );
- mon++; // in class Calendar & GregCal, months run 0-11 ;-(
- System.out.println( mon + "/" + date + "/" + year);
-
- If you want to build a string that has a formated date consider using
- SimpleDateFormat.format().
-
- 19. (Sect. 9) Some people use Calendar.getInstance() while others use new
- GregorianCalendar(). Which one is the correct way to get a Calendar?
-
- [*] Either way is correct, it depends on what you want to be able to
- do. You should use Calendar.getInstance(), if you want your code to be
- ready when the loading of other Calendars are added to the JDK and some
- other calendar is the default for the locale. A particular locale might
- have configured a Hebrew or Islamic Calendar as the default calendar
- and you might want a user to enter a date in his own Calendar, i.e.
- 1-Jan-2000 (Gregorian) = 23-Tevet-576 (Hebrew) = 24-Ramadan-1420
- (Islamic). If you really are trying to place a particular Gregorian
- date, i.e. 4-July-1776, into a Date object, you might as well create a
- GregorianCalendar directly.
-
- 20. (Sect. 9) I changed a field using Calendar.set() and then I checked
- another field. Its value is inconsistent with the value I just set.
- What is going on?
-
- [*]In JDK 1.1.0 the Calendar class did not update all of its fields
- until you called getTime to retrieve the Date that cooresponds to the
- fields in the Calendar. To get the earlier version of the Calendar to
- "turn the crank" and calculate all fields you can use the trick:
-
- myCal.setTime( myCal.setTime() ) // pull the date out and put it back
- in.
-
- 21. (Sect. 9) When I create the date July 4th, 1776 using new
- GregorianCalendar( 1776, 7, 4 ) the month is off by one. What is the
- problem?
-
- [*]You need to be be aware that months start with January equal to 0. A
- better way to create that date would be:
-
- independanceDayUSA = new GregorianCalendar( 1776, Calendar.JULY, 4 );
-
- 22. (Sect. 9)Why aren't there constants for milliseconds per day, week or
- year?
-
- [*]The short answer is: these values are not constants. While some date
- calculations would find these useful, it is important to remember that
- in areas with daylight savings time rules, there are two days per year
- that are not 24 hours long, therefore not all weeks are the same length
- (2 out of 52). Also, because of leap years, not all years are the same
- length.
-
- If you adding values to a calendar consider using either add or roll;
- for example:
-
- myCal.add(Calendar.YEAR, 1 ); // get a value 1 year later.
-
- 23. (Sect. 9) By my count the week of the Year is off by one. What is the
- problem?
-
- [*]The GregorianCalendar class uses the value set by
- setMinimalDaysInFirstWeek() to determine if the fractional week at the
- beginning of the year should be week 1 or week 0. If you don't change
- it, any fractional week could be week 1, depending on the value defined
- for the locale.
- 24. (Sect. 9) What timezone does a calendar use when I don't explicitly set
- one?
-
- [*]The Calendar uses the TimeZone.getDefault() (see discussion under
- TimeZone).
-
- 25. (Sect. 9) Should I stop using Date all together and just use Calendar?
-
- [*] Probably not. The Calendar class is a much larger than a Date
- object. Many other interfaces in standard APIs are defined using a Date
- object. Use Date objects to hold, store or communicate a date-time
- value. Use a Calendar object to manipulate a date-time value.
-
- 26. (Sect. 9) The GregorianCalendar will not accept a date prior to 4713
- B.C. Why?
-
- [*]January 1, 4713 B.C. is the "epoch" date for the Julian Day calendar
- which was invented in the 16th century by the Joseph Justus Scaliger.
- "[T]he Julian day calendar, ... does not use individual years at all,
- but a cycle of 7980 astronomical years that counts a day at a time,
- with no fractional days, no mean year, and no leap years. He came up
- with his number by mulitplying three chronological cycles: an 18-year
- solar cycle, a 19-year lunar cycle, and the 15-year indication period
- used by Romans. All three cycles began together at the same moment at
- the start of the "Julian cycle. ... [This] Calendar lives on among
- astronomers."
- -- David Ewing Duncan, "Calendar", Avon Books, 1998; p 207
-
- Note that the Julian Day calendar is not the same as the Julian
- calendar. The Julian Calendar is named for Julius Caesar. The Julian
- Calendar was used in the Europe from what we now call January 1, 45
- B.C. until at least October 4, 1582 and is still used today by the
- Eastern Orthodox Church to date holidays.
-
- The limitation on dates prior to 4713 BC has been dropped in JDK 1.2.
-
- 27. (Sect. 9) The Calendar class is said not to handle certain historical
- changes. Can you explain some of the limitations?
-
- [*]The date of change from the Julian to the Gregorian calendar depends
- on where you lived at the time. The date can vary from 1582 (most
- Catholic countries, which of course followed the Papal edict) to 1949
- (China). The date of the cutover from using the Julian Calendar (leap
- years ever 4 years) to using the Gregorian Calendar (every 4 years,
- except every 100 unless divisable by 400) is controlled by the method
- GregorianCalendar.setGregorianChange(Date).
-
- It is also the case that January 1 was not always the beginning of the
- year. January 1 was standardized by Julius Caesar in 45 B.C. and Pope
- Gregory XIII in 1582, but others who used the Julian Calendar between
- those dates used other dates for New Years Day. (Anyone who has ever
- been involved in a standardization effort may find it interesting that
- neither an emperor nor a pope could actually complete the
- standardization effort).
-
- The Calendar class uses a TimeZone which does not handle historical
- changes, i.e. the SimpleTimeZone contains only two dates the "spring
- forward" and "fall back" dates and a date that the DST starts (see
- SimpleTimeZone.setStartYear() ). If the local definitions have changed
- then a date/time may not accurately reflect the historical local time.
-
- As noted above, the Date object does not usually include leap seconds,
- unless your hardware includes leap seconds.
-
- While the Calendar class is more than useful for international
- business, it may not be what you want for doing UTC timebased
- calculations or historical dates and times without a more careful
- analysis of its design limits.
-
- java.text.DateFormat and java.text.SimpleDateFormat
-
- 28. (Sect. 9) How do I convert a date in one format to another?
-
- [*] The following code illustrates the technique:
-
- import java.text.*;
- public class DateTest {
- public static void main( String[] args ) {
- SimpleDateFormat df1 =
- new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
- SimpleDateFormat df2 =
- new SimpleDateFormat("dd-MMM-yy");
- String startdatetime = "1998-09-09 06:51:27.0";
-
- try {
- System.out.println("Date is " +
- df2.format( df1.parse(startdatetime) ));
- } catch (ParseException pe) {
- System.out.println("ParseException " + pe );
- }
- }
- }
-
- When run, the program outputs "Date is 09-Sep-98"
- 29. (Sect. 9) How do I use DateFormat to parse a string containing a date?
-
- [*] The easiest way to parse a date that is in a known format is to use
- SimpleDateFormat.parse().
-
- DateFormat df = new SimpleDateFormat( "HH:mm" );
- df.setTimeZone( TimeZone.getDefault() ); // if using JDK 1.1 libraries.
- df.setLenient( false ); // to not allow 26:65 etc.
- Date lateLunchOnDayZero = df.parse( "12:30" );
- System.out.println( lateLunchOnDayZero );
-
- The above code would result in (when in the MST timezone).
-
- Thu Jan 01 12:30:00 MST 1970
-
- To parse other date and time fields, refer to the SimpleDateFormat
- documentation.
-
- 30. (Sect. 9) How do I use a DateFormat to create a text string from a
- Date?
-
- [*] The easiest way to create a string from a date is to use a
- SimpleDateFormat.format(). The following code illustrates how this can
- be done.
-
- DateFormat df = new SimpleDateFormat( "yyyy.MMM.dd HH:mm:ss.SSS z" );
- df.setTimeZone( TimeZone.getDefault() ); // JDK 1.1
- System.out.println( df.format( d ) ); // where d is a Date
-
- For other possible fields from the calendar, see the document for
- SimpleDateFormat.
-
- 31. (Sect. 9) What timezone does a SimpleDateFormat use when I don't
- specify one?
-
- [*]In JDK 1.1, the SimpleDateFormat uses the first timezone defined for
- the locale. In JDK 1.2, it uses the default timezone. See the
- discussion above on how this differs from the Calendar class).
-
- 32. (Sect. 9) I'm not yet using JDK 1.2 and I don't want the DateFormat to
- use the 1st timezone for the locale. How do I change the timezone in a
- SimpleDateFormat to use a different timezone?
-
- [*] The following code sets the timezone of a DateFormat to the current
- default.
-
- DateFormat df = DateFormat.getDateInstance();
- df.setTimeZone(TimeZone.getDefault());
-
- or to set it to a timezone of your chioce.
-
- df.setTimeZone(TimeZone.getTimeZone( "MST" ) ) // Mtn Time, Denver USA
-
- 33. (Sect. 9) What century is assumed when I use a two digit year in a
- SimpleDateFormat string?
-
- [*]In JDK 1.1, the default start for the century used by
- SimpleDateFormat for 2 digit years is 80 years before the current date.
-
- This means that in 1998: 1 = 2001, 2 = 2002, ... 17 = 2017, 18 = 2018,
- 19 = 1919, 20 = 1920, ... 98 = 1998, 99 = 1999,
-
- In JDK 1.2 you can change this "default century start date" with the
- method set2DigitYearStart( Date) and get its current value
- with the method get2DigitYearStart(). One thing to note is that since
- set2DigitYearStart takes a date not a year, you can have your default
- century begin at any day or hour.
-
- When running under JDK 1.1, it is probably best to avoid two-digit year
- fields, when the dates entered could possibly fall outside of the range
- -- now less 80 years and now plus 20 years. If you want to allow
- two-digit year fields in JDK 1.2 and beyond, consider setting the
- 2DigitYearStart property to something appropriate, For example, set it
- to today, when all dates to be entered are in the future (i.e. an
- expiration date), or set it to today less 100 years, when the value is
- always in the past (i.e. birthdate, death date).
-
- 34. (Sect. 9) Does the above mentioned limitation of 2 digit years in JDK
- 1.1 mean that java.text.SimpleDateFormat is not Y2K compliant?
-
- [*] No. It means that any code you write that (1) allows the entry of 2
- digit years and (2) does not make sure they are in an appropriate
- century, would not pass a careful Y2K analysis. This code was put here
- so you could sensibly read old files with non-Y2K compliant dates, not
- so you could create new ones. Once you are using JDK 1.2 it is better
- to set the 2DigitYearStart property to something appropriate for any
- two-digit year field which you are parsing.
-
- java.sql.Date and java.sql.TimeStamp
-
- 35. (Sect. 9) What timezone does a java.sql.date use when converting to an
- SQL DATE?
-
- [*]This is another hidden use of the default java.util.TimeZone. If you
- have carefully set every timezone in every Calendar and DateFormat you
- are using, but you don't set the default in java.util.TimeZone when a
- java.util.Date is converted to a java.sql.Date you may not end up with
- the value you expected in your database.
-
- 36. (Sect. 9) When I print a jave.sql.Timestamp it doesn't include any
- milliseconds. What is the problem?
-
- [*] If you print the java.sql.Timestamp directly you will see this
- problem. The following code demonstrates this surprising behavior.
-
- // incorrect use of java.sql.Timestamp
- DateFormat df = new SimpleDateFormat( "MM/dd/yy hh:mm:ss.SSS a" );
- df.setTimeZone( TimeZone.getDefault() ); // needed in JDK 1.1
-
- java.sql.Timestamp t = new java.sql.Timestamp( 94, Calendar.JANUARY, 1,
- 13, 45, 59, 987654321 );
- System.out.println( df.format( t ) ) ; // Wrong! no fractions of a second.
-
- The results of the above code are:
-
- 01/01/94 01:45:59.000 PM
-
- The above code is using whatever is in the super class (java.util.Date)
- and assumes all of those parts are filled in. java.sql.Timestamp could
- have stored the whole milliseconds in the millisecond part of a
- java.util.Date, and stored the nanoseconds that are not whole
- milliseconds in an additional field. They chose to ignore the fractions
- of a second in the java.util.Date and put all fractional parts in an
- additional nanosecond field.
-
- The following code shows how to convert a java.sql.timestamp to a
- java.util.Date.
-
- Date d = new Date(t.getTime() + (t.getNanos() / 1000000 )); // 1 Milli = 1x10^6
- Nanos
- System.out.println( df.format( d ) ) ; // Right! At least we have the millis
-
- The result of the above code is a better approximation of the timestamp
- value:
-
- 01/01/94 01:45:59.987 PM
-
- -------------------------------
-
- 10. AWT
-
- Text, Textfield, and TextArea
-
- 1. (Sect. 10) How can I write text at an angle?
-
- [*] Check out http://www.nyx.net/~jbuzbee/font.html. Jim has some code
- to do exactly this. A good way to do it is to draw the text to an
- offscreen image and write an ImageFilter to rotate the image.
-
- Also, from JDK 1.2 on, the Java 2D API handles arbitrary shapes, text,
- and images and allows all of these to be rotated, scaled, skewed, and
- otherwise transformed in a uniform manner. There is more info about the
- 2D API at http://java.sun.com/products/java-media/2D/index.html and
- http://developer.javasoft.com/developer/technicalArticles/
-
- 2. (Sect. 10) How do you change the font type and size of text in a
- TextArea?
-
- [*] Like this.
-
- myTextArea.setFont(new Font("NAME", <STYLE>, <SIZE>));
-
- where:
- o NAMEis the name of the font (e.g. Dialog or TimesRoman).
- o <STYLE> is Font.PLAIN, Font.ITALIC, Font.BOLD or any additive
- combination (e.g. Font.ITALIC+Font.BOLD).
- o <SIZE> is the size of the font, e.g. 12.
-
- Example: new Font("TimesRoman", Font.PLAIN, 18);
-
- 3. (Sect. 10) Can you have different fonts for individual words in a
- TextArea?
-
- [*] No. If you're trying to write a word processor, use the Canvas
- class to render on. Note that this can be done using the Swing JText
- classes.
-
- 4. (Sect. 10) How much text can be put in a TextArea?
-
- [*] TextArea just uses the corresponding widget of the underlying
- window system. It will be bounded by the limit imposed in the native
- window system. In Windows 95 TextAreas can hold about 28Kb. The native
- widget allows 32Kb, but there is some overhead which reduces the amount
- available to the programmer. The limit is removed in JTextComponent in
- Swing (JDK 1.2) which dispenses with peer controls.
-
- 5. (Sect. 10) How do I clear the contents of a TextArea?
-
- [*] Set it to an empty String with this:
-
- area.setText("");
-
- 6. How do I get back to a normal echo after I have used
- TextField.setEchoChar('*')?
-
- [*] TextField.setEchoChar('\0') works on most Windows-based
- browsers...but for most other platforms (i.e. Netscape under UNIX), it
- just locks up the textfield.
-
- There is only one good solution, and that is to make two TextFields on
- top of each other, one normal, and one with .setEchoChar('*'), and
- switch between them.
-
- 7. (Sect. 10) How do I get word wrap in a TextArea?
-
- [*] It's a little obscure. Creating a TextArea with no horizontal
- scrollbar causes wrapping to occur automatically. The idea is that if
- you ask for a scroll to scroll viewing over to the right, there is no
- reason for the widget to do word wrap. So take away the scrollbar, and
- word wrap will be done instead.
-
- Supply TextArea.SCROLLBARS_NONE or TextArea.SCROLLBARS_VERTICAL_ONLY to
- the TextArea constructor to get word wrap. By default, a TextArea is
- created with both horizontal and vertical scrollbars.
-
- 8. (Sect. 10) How can I limit a TextField to no more than N characters, or
- to only allow numeric input?
-
- [*] The approach is to look at keystrokes as they happen, and disallow
- input that does not meet your criteria.
-
- A neat variation is to extend the basic AWT component, and in your
- subclass also include the handler that will look at the keystrokes.
- This bundles everything neatly in one place. The code may look like:
-
- import java.awt.*;
- import java.awt.event.*;
- public class XCTextField extends java.awt.TextField implements
- java.awt.event.TextListener {
-
- public XCTextField(int columns) {
- super(columns);
- enableEvents(AWTEvent.FOCUS_EVENT_MASK);
- addTextListener(this);
- }
-
- // other constructors may be useful, too
-
- public void textValueChanged(java.awt.event.TextEvent event) {
- int col = this.getColumns();
- int len = getText().length();
- // int caret = getCaretPosition();
-
- if (col > 0 && len > col) {
- // or if the char just entered is not numeric etc.
- String s = this.getText();
- Toolkit.getDefaultToolkit().beep();
- this.setText(s.substring(0,col));
- this.setCaretPosition(col-1); // caret at end
- }
-
- }
-
- public void processFocusEvent(java.awt.event.FocusEvent e) {
- // this routine highlights according to focus gain/loss.
- super.processFocusEvent(e);
- int id = e.getID();
- if (id==java.awt.event.FocusEvent.FOCUS_GAINED)
- this.selectAll();
- else if (id==java.awt.event.FocusEvent.FOCUS_LOST)
- this.select(0,0);
- }
- }
-
- Here is a much briefer example, which very cleverly does the work in
- the Listener. Oracle really dislikes the "apostrophe" character in a
- data text fields, as it is interpreted as part of an SQL statement.
- Here is the code that James Cloughley wrote to suppress apostrophes
- ("ticks") in a TextField.
-
- import java.awt.*;
- import java.awt.event.*;
- public class NoTick extends KeyAdapter {
- final char tick = '\'';
-
- public void keyPressed( KeyEvent event ) {
- TextComponent tc = ( TextComponent )event.getSource();
- char c = event.getKeyChar();
- if ( c == tick ) { event.consume(); }
- }
- }
-
- Use it like this:
-
- TextField sometextfield = new TextField();
- sometextfield.addKeyListener( new NoTick() );
-
-
- Brief and clever - make the event handler consume unwanted characters.
- However, it doesn't filter out text that arrives in the component via
- cut & paste! If you use ctrl-v to paste, you get key events for the
- ctrl and v, but not for the characters that are pasted.
-
- Finally, check out iDate, iTime, and iNumeric from IBM's alphaworks
- javabeans, available free at http://www.alphaworks.ibm.com/alphaBeans.
- These beans do the kind of validation you want.
-
- Size and Position
-
- 9. (Sect. 10) I use add(Component) to add Components to the Container. Is
- there any way to explicitly set the z-order of these Components?
-
- [*] JDK 1.0 has no way to explicitly set the z-order of components. You
- can try it heuristically, based on the browser you're using, or you can
- use CardLayoutManager to ensure the panel you want is at the front.
-
- In JDK 1.1, the z-order of components ("z-order" means "front-to-back"
- order, i.e. which window is in front of which) can be controlled by
- using the the method add(Component comp, int index). By default,
- components are added 0 to N. The method paint of class Container paints
- its visible components from N to 0.
-
- 10. (Sect. 10) How can I get the dimensions and resolution of the screen?
-
- [*] Use
-
- java.awt.Toolkit.getDefaultToolkit().getScreenSize()
-
- or
-
- java.awt.Toolkit.getDefaultToolkit().getScreenResolution()
-
- Screen resolution is in dots-per-inch.
-
- Take a look in the Toolkit class for other useful methods.
-
- Toolkit.getDefaultToolkit().getColorModel().getPixelSize()
-
- gets you the color model in terms of bits per pixel.
-
- Math.pow(2, Toolkit.getDefaultToolkit().
- getColorModel().getPixelSize())
-
- gets you the color model in terms of number of colors. Or use this:
-
- 1 << Toolkit.getDefaultToolkit().
- getColorModel().getPixelSize()
-
- That does a shift left to calculate the power of two.
-
- 11. (Sect. 10) How do I allow for the size of the title bar and border when
- I draw a Frame?
-
- [*] Use MyFrame.getInsets(). This returns a java.awt.Insets object
- which has four ints: top, left, bottom, right, giving the number of
- pixels each of those margins are inset from the top. You can use these
- value to adjust the Dimension object returned by component.getSize().
-
- If you are doing this in the constructor you need to ensure that the
- Frame's peer object is created first. Otherwise the Insets object
- returned by getInsets() will have all zero values. Make a call to
- Frame.addNotify() to have the peer created.
-
- 12. (Sect. 10) How do I resize a List? I had a List defined as
-
- List tlist = new List(10);
-
- but the Strings in the list were 80 characters long and only the first
- 15 were being shown. I was not able to resize the List to display the
- contents without using the scroll bar.
-
- [*] A List cannot be resized in a constructor, so add the following to
- the Applet (or wherever):
-
- public void paint (Graphics g) {
- tlist.setSize(200,200);
- }
-
- Then before showing panel/frame with the List:
-
- tlist.resize(400,400);
-
- 13. (Sect. 10) How can my program tell when a window is resized?
-
- [*] Override the setBounds(int,int,int,int) method of Component to do
- what you want. Of course, have it call super.setBounds() as well. Note
- that setBounds() replaces reshape() which is deprecated.
-
- Note the new APIs call the deprecated APIs instead of the other way
- round. For example, Component.setBounds calls Component.reshape,
- instead of reshape calling setBounds. This is because the AWT sometimes
- needs to call these for its own purposes. If it called the old one
- which then called the new one, and you overrode the new one, the AWT
- would (wrongly) not call your routine. By having the AWT call the new
- one (and then the new one call the old one), any overrides of the new
- one will correctly be called by the AWT as needed. If that didn't make
- sense, forget I mentioned it.
-
- 14. (Sect. 10) How do I center a dialog box?
-
- [*] You cannot currently get the applet's absolute screen coordinates.
- Its location (0,0) is relative to the browser, not the screen itself.
- But you can center something that it pops up or displays centered on
- the screen with code like this:
-
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- my_window.move(
- ( screen.width - window.size().width ) / 2,
- ( screen.height - window.size().height ) / 2 );
-
- my_window.show().
-
- In a related fashion, you can center something on its parent like this.
- Note the intelligent use of APIs like translate() to do the work for
- you.
-
- void center(Component parent) {
- pack();
-
- Point p = parent.getLocation();
- Dimension d = parent.getSize();
- Dimension s = getSize();
-
- p.translate((d.width - s.width) / 2,
- (d.height - s.height) / 2);
- setLocation(p);
- }
-
- 15. (Sect. 10) How can I get the absolute mouse coordinates?
-
- [*] You mean, if the browser is about 640x480, you want a y-coord
- between 0 and 480. If the browser window is about 800x600 you want a
- y-coord between 0 and 600. This might be needed for a pop-up menu,
- where you want to pop up at the absolute mouse position.
-
- The approach is to sum up the event's (x,y) and the locations of the
- target and its parents until there is no parent. Though on some
- browsers, it seems this is not reliable. [Better suggestions are
- solicited.]
-
- 16. (Sect. 10) How do I detect a resize of a Frame or other Component?
-
- [*] If you are using JDK 1.0.2, you can override the reshape(int, int,
- int, int) method of Component to do what you want; of course, have it
- call super.reshape() as well.
- In JDK 1.1.x, setBounds() replaces reshape(), which is deprecated -
- however, there is a better way of detecting the resize using the new
- event model, than overriding setBounds(). Note the new APIs call the
- depecated one.
-
- The proper way to detect the resize in 1.1.x is to register a
- ComponentListener on the Frame, like this:
-
- import java.awt.*;
- import java.awt.event.*;
-
- class MyFrame extends Frame {
- public MyFrame() {
- addComponentListener(new CmpAdapter());
- }
-
- class CmpAdapter extends ComponentAdapter {
- public void componentResized(ComponentEvent evt) {
- //doSomething();
- }
- }
- }
-
- Alternatively, the same effect can be achieved like this:
-
- class MyFrame extends Frame implements ComponentListener {
- public MyFrame() {
- addComponentListener(this);
- }
-
- public componentHidden(ComponentEvent evt) { }
- public componentMoved(ComponentEvent evt) { }
- public componentShown(ComponentEvent evt) { }
- public componentResized(ComponentEvent evt) {
- //doSomething
- }
- }
-
- Or even with an anonymous inner class
-
- public MyFrame() {
- addComponentListener(new ComponentAdapter() {
- public void componentResized(ComponentEvent evt) {
- // doSomething;
- }
- } );
- }
-
- 17. (Sect. 10) What are those preferredSize() and minimumSize() methods in
- Component?
-
- [*] Those methods allow a LayoutManager to calculate the preferred and
- minimum sizes of the Components it is arranging. You can control the
- values that the LayoutManager gets by creating subclasses of the
- Components you are using and overriding these methods.
-
- Drawing and Pixels
-
- 18. (Sect. 10) How do I plot a single pixel to the screen?
-
- [*] Use g.drawLine(x1,y1,x1,y1) to draw a line one pixel in length. If
- you are drawing a very large number of individual pixels, consider
- using a java.awt.MemoryImageSource object and measure whether this
- offers better performance.
-
- 19. (Sect. 10) Is it possible to draw a polygon or a line more than 1 pixel
- wide?
-
- [*] JDK 1.1.1 doesn't have support for this. The standard workaround
- for drawing a thick line is to draw a filled polygon. The standard
- workaround for drawing a thick polygon is to draw several polygons.
-
- There is a useful class at
- http://www.apl.jhu.edu/~hall/java/GraphicsUtil.html which extends the
- drawxxx and fillxxx methods of java.awt.Graphics. It adds a Line Width
- argument to most of the drawxxx methods, a Color argument to most of
- the drawxxx and fillxxx methods, and a Font argument to drawString and
- drawChars.
-
- 20. (Sect. 10) How can I make an offscreen image with transparent pixels?
- How can I grab the pixel values from an offscreen image?
- How can I use AWT drawing primitives (e.g. drawString() or drawOval())
- on an image I created from an ImageProducer?
-
- [*] None of these things can be done.
-
- Despite the fact that there is only one class called Image in the AWT
- libraries, it suffers from a (currently undocumented) severe case of
- schizophrenia: The code behaves as though there are two unrelated types
- of Image. The first type are those created by the
- Component.createImage(int, int) call, known as "offscreen" images, and
- the second are those created by the
- Component.createImage(ImageProducer) call, or by the
- Toolkit/Applet.getImage() calls, which I will call "produced" images.
-
- The only common ground between these kinds of Image is the following:
- o You may find their width and height by the methods of the Image
- class.
- o You may use them as the argument to the various
- Graphics.drawImage() calls.
- The differences between these objects are the following:
- o You may not put transparent pixels into an offscreen - note that
- all Java primitives accept Color objects, which all represent
- completely opaque colours as if Produced from an int with the
- upper 8 bits equal to 0xff. (See also Question 8.3.)
- o You may not call Image.getGraphics() on a produced image, and
- hence may not use any AWT primitives.
- o You may not grab pixels from an offscreen image using
- PixelGrabber.
- o Anyone know of any other limitations?
- In these cases, "you may not" generally means "you may not
- successfully". Symptoms on attempting these range from Exceptions to
- garblings of the Image. Any or all of these restrictions may be removed
- in Java 1.2, which features a new 2D API. Wait and see.
- Workaround: cause a peer to be created for the Image, and then do the
- operation. It will work. You can add it to a Frame, for example. You do
- not have to show() the Frame. Causing the peer to be created is enough.
-
- There are some relevant bugs shown in the Java Developer Connection:
- Bug ID 4098505. Apparently, from the report from the Sun engineer,
- PixelGrabber is specified to work with offscreen images, just it is
- currently buggy, and invariably gets the wrong color model. No fix has
- been scheduled yet.
-
- Bug ID 4077718 reports that setting transparent Colors in offscreen
- images has been available since Java 1.2b1. I am personally unable to
- verify this.
-
- There is an incorrect answer from Sun to the third matter, of
- getGraphics() on produced images, in article 1501 in Questions&Answers.
-
- 21. (Sect. 10) How can I grab a pixel from an Image object?
-
- [*] This is the purpose of the java.awt.image.PixelGrabber class. A
- fragment of code showing its use is:
-
- import java.awt.image.PixelGrabber;
- import java.awt.Image;
- ...
- public static int pixelValue(Image image, int x, int y) {
- // precondition: buffer must not be created from ImageProducer!
- // x,y should be inside the image,
- // Returns an integer representing color value of the x,y pixel.
- int[] pixel=new int[1];
- pixel[0]=0;
-
- // pixel grabber fills the array with zeros if image you are
- // trying to grab from is non existent (or throws an exception)
- PixelGrabber grabber = new PixelGrabber(image,
- x, y, 1, 1, pixel, 0, 0);
- try {
- grabber.grabPixels();
- } catch (Exception e) {System.err.println(e.getMessage());}
- return pixel[0];
- }
-
- By the way, one issue on working with images is that the Java VM will
- consume virtual memory pretty fast if you are loading lots of images
- without calling the Image.flush() method when done. The getImage()
- method probably caches old images so they aren't garbage collected.
-
- Other AWT FAQs
-
- 22. (Sect. 10) How do I change the icon on my Frame or JFrame from the Java
- coffee cup to my own icon?
-
- [*] Just use
-
- f.setIconImage( Toolkit.getDefaultToolkit().getImage(iconfilename) );
-
- 23. (Sect. 10) What's all this about subclassing Canvas and overriding
- paint() ? Can't I just do a getGraphics() for a component, and draw
- directly on that?
-
- [*] You can do that, and it might work up to a point (or it might not).
- A problem arises when the window system wants to refresh that component
- e.g. because it has been partially obscured and is now revealed. It
- calls paint(), and paint() has no knowledge of the other g.drawing()
- you have just done.
-
- 24. (Sect. 10) But couldn't the AWT just remember what has been drawn to a
- Graphics context, and replicate that instead of calling paint()?
-
- [*] Possibly it could, but how do you unremember something that has
- been drawn? How do you start drawing over again with different
- contents? You could solve these by creating extra methods, but that is
- not how it works. In practice it is a lot simpler to be able to look at
- the paint method, and see explicitly all the things that will be done
- to draw that component. Bottom line: Use paint(), not g=getGraphics();
- g.drawString( ...
-
- 25. (Sect. 10) When I call repaint() repeatedly, half my requests get lost
- and don't appear on the screen. Why is this?
-
- [*] repaint() just tells the AWT that you'd like a paint to happen. AWT
- will fold several adjacent repaint requests into one, so that only the
- most current paint is done. One possible workaround might be to use a
- clip rectangle and only paint the different areas that have changed.
- 26. (Sect. 10) Why do I get this when using JDK 1.1 under X Windows?
-
- java.lang.NullPointerException
- at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59)
- at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153)
- at java.awt.Frame.addNotify(Frame.java)
- at java.awt.Window.pack(Window.java)
-
- [*] There's a missing font on your system. Move font.properties from
- the "lib" subdirectory aside to font.properties.bak. Then it won't look
- for the font and fail to find it.
-
- The problem occurs because the Motif AWT libraries use the Font "plain
- Dialog 12 point" as a fall-back default font. Unfortunately, when using
- a remote X server sometimes this font isn't available.
-
- On an X terminal, the diagnostic may be slightly different, a segv
-
- % appletviewer HelloWorldApplet.html
- SIGSEGV 11* segmentation violation
- si_signo [11]: SIGSEGV 11* segmentation violation
- si_errno [0]: Error 0
- si_code [1]: SEGV_ACCERR [addr: 0x14]
-
- To determine which fonts you have, issue a command such as
-
- xlsfonts > ~/fonts.txt
-
- Then pick through the long list of fonts to determine which ones you
- want to use. The xfd program will let you look at a font:
-
- xfd -fn "your font name here" &
-
- 27. (Sect. 10) Why is GridBagLayout so hard to use?
-
- [*] There are two reasons. First, while simple layouts are easy.
- detailed GUI layout is difficult. Second, GridBagLayout wasn't designed
- with human factors and ease of use in mind. If that bothers you (it
- bothers me) then don't use it. Create your GUI on several panels and
- use the other layout managers as appropriate to get the exact effect
- you want. The official story from the project leader of the AWT
- project, as explained to the Mountain View Java Users Group on December
- 4 1996, is:
- "The case has been made and is now accepted that GridBagLayout is
- too hard to use for what it offers. GBL will continue to be
- supported, and something better and simpler will eventually be
- provided as well. This 'better GBL' can be used instead of GBL."
- Bottom line: nobody has to spend any effort on GBL, there are better
- alternatives available now, and it will be replaced by the SwingSet
- "SpringLayout" Springs & Struts style layout manager.
-
- SpringLayout was to be introduced as part of the Java Foundation
- Classes with JDK 1.2, but it was dropped from the beta release as the
- code was not ready in time. Javasoft generously made the preliminary
- code available and invited programmers to hack on it and submit the
- results.
-
- 28. (Sect. 10) MyClass works fine except when I try to set a particular
- font. I just can't seem to get it to work in Win95, but I can get it to
- work on a MacOS and Unix.
-
- [*] You probably specified a font name that isn't available under your
- Win95 installation; this is one of those cross-platform differences
- that can bite you if you over-specify for one platform, like specifying
- "Arial" as a font and expecting it to work on something other than
- Windows.
-
- On both Windows 95 and Solaris 2.6, these fonts
- o Dialog
- o SansSerif
- o Serif
- o Monospaced
- o Helvetica
- o TimesRoman
- o Courier
- o DialogInput
- o ZapfDingbats
- are revealed by this code:
-
- import java.awt.*;
-
- class foonly {
- static public void main(String s[])
- {
- String n[]= new Frame().getToolkit().getFontList();
- for (int i=0;i<n.length; i++)
- System.out.println(n[i]);
-
- System.exit(0);
- }
- }
-
- In other words, You can get a String array of the names of the fonts by
-
- String[] fonts = Toolkit.getDefaultToolkit().getFontList()
-
- The names of actual fonts like Helvetica, TimesRoman, and Courier are
- deprecated in JDK 1.1 in favor of font styles like SansSerif, Serif,
- and Monospaced (respectively). The font style will be mapped into the
- nearest actual font on a platform.
-
- The font styles are now mapped into a system font name using the
- entries in one of the font.properties files in $JAVAHOME/lib. There are
- multiple font.properties files corresponding to different locales. If
- you wanted a quick hack for testing, you could modify the file or add
- to it so a different mapping is done to a new font you want to try.
-
- 29. (Sect. 10) I've made a Lightweight Component (a Component directly
- extending Component), and it keeps flickering/doesn't repaint itself
- properly. Why is this?
-
- [*] Lightweight Components, since they are notionally meant to be
- "transparent", aren't painted directly in response to repaint(), but in
- fact, Component.repaint() goes up the stack of Components until it
- finds an "Opaque" Heavyweight Component (necessarily a Container), and
- then calls repaint() on *that*.
-
- At this point, a call is eventually scheduled to Container.update().
- His first action is to call super.update, plunging us into
- Component.update(), which clears the component to the background color,
- since it has been called on a heavyweight, and returns. Then
- Container.update() proceeds merrily to call update on all contained
- Lightweight Components, recursively.
-
- The bottom line: "transparency" of lightweight components will only
- work correctly (without flickering) if the first upwardly accessible
- heavyweight component in the containment hierarchy is
- o a double-buffered heavyweight Component (necessarily a Container),
- or
- o a heavyweight that never updates, but always paints (i.e. one that
- has overriden the default update() mechanism to not clear the
- background).
- If this is not done, the default Component update() will always clear
- the background before any repainting is done, leading to annoying
- flickering.
-
- Another important point is that if your Container has its own paint()
- method, that paint method of the container must call
- super.update/paint(), otherwise the contained lightweight components
- will never be painted. Putting this all together, the minimal
- alteration to code to cause it to work in this case is to place the
- method
-
- public void update(Graphics g) {
- super.paint(g);
- }
-
- in the most closely containing heavyweight Container, in a Component
- hierarchy where you want to smoothly render lightweights that do not
- paint areas extending past that painted by their parents, i.e. ones
- that are not "transparent". This is dirty, but quick.
-
- If you want smooth transparency, the call above should read
-
-
- public void update(Graphics g) {
- // standard offscreen generation here.
- offg.fillRect(required background colour, full size);
- super.paint(offg);
- g.drawImage(offg, 0, 0, null);
- }
-
- public void paint(Graphics g) {
- // can generally expect resizes will hit update() first.
- super.paint(offg);
- g.drawImage(offg, 0, 0, null);
- }
-
- It's possible to intertwine these, by having this.update() calling
- this.paint(), with various replacings of the argument, but it is
- clearest to override them separately, like this.
-
- 30. (Sect. 10) What is the difference between Component's
- setForeground(Color c) and Graphics's setColor(Color c) ?
-
- [*] First of all, these methods do the same thing: Set the foreground
- color to the value of the parameter. The difference lies in where you
- use them. There is also a Component.setBackground that will set the
- background color.
-
- If you are in a constructor or an event handler (e.g. "click here to
- turn the canvas blue") you have a Component and should use the
- setForeground() method. If you are in a paint() method, that takes a
- Graphics context as its argument so you will typically use
- g.setColor(c).
-
- Unlike a Component, a Graphics object doesn't have a background color
- and a foreground color that you can change independently. A Graphics
- object arrives in the color(s) inherited from the drawing surface. From
- then on, any rendering (drawLine(), drawRect(), fillOval(), etc.) will
- be done in the setColor() color. Because they do different things, the
- Component and Graphics methods have different names.
-
- 31. (Sect. 10) When I start a mouse drag inside a Component, and go outside
- the Component, still dragging, the mouse events still get sent to the
- Component, even though I am outside it. Is this a bug?
-
- [*] No, it is the specified behavior. The Java API documentation says:
- "... Mouse drag events continue to get sent to this component even
- when the mouse has left the bounds of the component. The drag
- events continue until a mouse up event occurs...."
- It is done for the convenience and ease of the application programmer.
- It allows you to handle all drags from the place of origin. If you
- don't want this, simply look at the coordinates of the mouseDrag Event,
- and if they are outside the Component, ignore them.
-
- 32. (Sect. 10) Why doesn't my window close when I click on the X in the
- title bar?
-
- [*] Here's how to make your program do that.
- o JDK 1.0.2: Handle Event.WINDOW_DESTROY to do a hide() and
- dispose() on the Frame.
- o JDK 1.1:
- + Listen for WindowEvent and do hide(); dispose(); in
- windowClosing() - this really ought to be the "default"
- behaviour, so was made so for a Swing JFrame.
- + Enable AWTEvent.WINDOW_CLOSING and do the hide() and
- dispose() in processWindowEvent().
- o JDK 1.2: The Component JFrame does a close by default (see section
- 10).
-
- 33. (Sect. 10) How can I force a synchronization of the graphics state,
- e.g. of a cursor change, or an animation frame to be rendered?
-
- [*] This is done by the sync() method in Toolkit. So just use:
-
- AnyComponent.getToolkit().sync();
-
- 34. (Sect. 10) How can I tab between components?
-
- [*] In JDK 1.0, you have to read the key press, and program it
- explicitly. JDK 1.1 supports tab and shift-tab (previous field)
- automatically. The tab order is the order that the components were
- added to the container.
-
- 35. (Sect. 10) What is the difference between "low level" and "semantic"
- events?
-
- [*] Low-level events are tied to a specific component (resizing a
- window, dragging the mouse, striking a key, adding a Component to a
- Container, etc.). Semantic events are those generated when you frob a
- control (move a scrollbar, click on a button, select from a menu,
- etc.), and the same kind of event can be generated by several different
- components. A Button and a List both fire an Action event when they are
- clicked on.
-
- To the programmer, the important difference is that you can change a
- low-level event such as the key value in a keypress, and it will
- display the new value. You can also consume low level events so that
- they do not appear in the widget. You can't do these things with
- semantic events - they have already "occurred" to the widget.
-
- Semantic events: Use the method addXListener() to add a listener object
- which implements the XListener interface to get XEvent objects
- delivered (usually via the AWTEventMulticaster). Low level events: Use
- the method enableEvents() and override performX() to grab those events
- in the object itself.
-
- 36. (Sect. 10) Is it possible to have a Java window float above all other
- windows. For example, a tool palette floats in a super-layer always
- above all the regular document windows on which you use the palette's
- tools?
-
- [*] On MS Windows, a Window object floats above all other windows,
- unlike a Frame, which is layered in with ordinary windows. This
- behavior yields a "floating" effect. Whether a Window object is really
- supposed to float is another question entirely.
-
- On Mac, a Window object is either layered in with other windows, just
- like a Frame is, or else it is entirely modal - depending on which VM
- you use. In Java - there appears to be no easy way to get floating
- behavior. If anyone knows otherwise, please send in your comments.
-
- 37. (Sect. 10) How can iconify/deiconify a window in Java?
-
- [*] There is no way in Java today to write code to force a window to
- iconify or deiconify. There is a way (tested on Windows and UNIX) to
- achieve this effect that involves creating and destroying peers, but it
- is not recommended. You can drop into native code to do it. The "party
- line" in JavaSoft is that it is because Java is an application
- language, not a window manager. Everyone wishes they'd add it.
-
- 38. (Sect. 10) How do I know which mouse button was pressed, and how often?
-
- [*] To handle mouse events you have to implement the MouseListener
- interface, or derive from the MouseAdapter class in order to use one of
- the mouse-handling methods. The MouseEvent argument passed to the
- handling methods contains fields that say which button was pressed, and
- the click count. Use code like this.
-
- public void mouseClicked(MouseEvent m) {
- boolean leftButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
- boolean centerButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
- boolean rightButtonPush =
- (m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;
-
- int click = m.getClickCount(); // might be 1,2,3 clicks or more
-
- You can also call at m.isPopupTrigger(). If it returns a true value,
- the user has asked for a pop-up menu. On a lot of window systems, the
- right mouse button is the trigger for pop-up menus.
-
- You can overload processMouseEvent for your component.
-
- public void processMouseEvent(MouseEvent e) {
- if (e.isPopupTrigger()) {
- // do what you want
- }
- else
- super.processMouseEvent(e);
- }
-
- The code above applies to JDK 1.1. You can also call
- java.awt.swing.SwingUtilities.isRightMouseButton(MouseEvent me).
-
- See also question 15.10.
-
- -------------------------------
-
- 11. Swing
-
- 1. (Sect. 11) What is Swing?
-
- [*] Swing is a new GUI toolkit bundled with JDK 1.2, and available as
- an add-on extension library for JDK 1.1. Swing is part of the Java
- Foundation Classes and supports a GUI toolkit that lets developers
- create components that have a pluggable look-and-feel. From an
- architectural standpoint, the Swing component set extends - but does
- not completely replace - the Abstract Windowing Toolkit (AWT).
-
- Swing has many components that can be used in place of components in
- the AWT (e.g. JFrame instead of Frame, JButton instead of Button,
- JApplet instead of Applet, JPanel instead of Panel). It also has many
- components that don't exist in the AWT (e.g. tool tips, toolbars, and
- progress bars). However Swing relies on the underlying AWT being there.
-
- The Swing toolkit allows the creation of GUI's that are every bit as
- sophisticated as native code toolkits like MFC -- with the Java
- advantage that they run on every platform. The pluggable look and feel
- means that they can have the same appearance on every platform, or you
- can choose to have it look like Windows on a PC, like Motif on a Unix
- box, etc, just as the user chooses.
-
- With Swing, native window behavior is confined to external window
- frames (and their borders) and a few other things such as fonts and the
- buffers used to hold window contents. The composition, layout, and
- drawing of controls is now all handled by Java code. So identical code
- is executed to create and manage your user interface on every platform.
- Swing provides a much greater consistency of behavior across different
- platforms.
-
- Swing works with JDK 1.1 if you download the swing.jar file and add it
- to your path. Swing is built in to JDK 1.2, and Javasoft has just
- changed its 1.2 Swing package-naming strategy. It is now called
- javax.swing.
-
- 2. (Sect. 11) Should I use Swing or AWT to build my GUIs?
-
- [*] Use Swing to build your apps now instead of AWT components,
- wherever you have a choice. Swing is a GUI toolkit that is at least as
- good as other commercial GUI toolkits, and better in several respects.
-
- With Swing, it is easier to build an application that is portable
- between Mac, Solaris, Windows 95 and NT, than it is to use Win32 and
- build an application that just runs on Windows 95 and NT.
-
- 3. (Sect. 11) Where can I find a Swing tutorial?
-
- [*] There is a Swing tutorial at
- http://java.sun.com/docs/books/tutorial/ui/swing/index.html which is
- part of this tutorial:
- http://java.sun.com/docs/books/tutorial/ui/TOC.html
- There is also a Swing FAQ at http://users.vnet.net/wwake/swing/faq.txt
- Please let this FAQ maintainer know about other good Swing tutorials
- and online resources.
-
- 4. (Sect. 11) What is the Model/View/Controller paradigm?
-
- [*] Model/View/Controller is a design pattern or framework originally
- developed by Prof. Trygve Reenskaug at Xerox PARC in 1978/9. MVC was
- developed to allow Smalltalk to conveniently support GUIs.
-
- Model/View/Controller is a design pattern used extensively in Swing.
- Basically, the "model" contains your data, the "view" is the graphical
- representation, and the "controller" is responsible for the interaction
- between the other two. As an example, think of visually editing the
- Tree widget that represents a directory. The display is the view.
- Selecting a file, and dragging it to the trash can will delete the
- file. In order for the delete to happen, the controller must tell the
- model what just happened in the view.
-
- In practice, inter-communication between the view and the controller is
- complex, so the two are bundled together in one category in Swing. The
- model (data) is separate though.
-
- There's a reasonable white paper on MVC in Swing at
- http://java.sun.com:81/products/jfc/swingdoc-static/swing_arch.html .
- There is information on other OO design patterns at
- http://www.parallax.co.uk/cetus/oo_patterns.html.
-
- 5. (Sect. 11) When I run the Swing demo on Windows 95 I get an error "Out
- of environment space."
-
- [*] That's because you don't have enough space for your DOS
- environment. You can fix this with:
- o Right click your MS-DOS Prompt icon or window and choose
- Properties.
- o Choose "Memory" and on "Initial Environment", choose 4096 instead
- of "auto".
- o Run Swing again, you'll be OK.
-
- 6. (Sect. 11) How can I run Swing code in a browser?
-
- [*] Most current browsers have to be specifically set up to run Swing
- applets. Read the article at
- http://www.javasoft.com/products/jfc/swingdoc-current/applets.html for
- information about this. The article also contains a simple Swing
- example applet, so you can confirm that that's your problem.
- Another approach is to use the Java plug-in, which automatically gives
- a Swing-compatible Java in the browser. See
- http://java.sun.com/products/jfc/tsc/swingdoc-current/java_plug_in.html
-
- 7. (Sect. 11) Why is my menu showing up behind other components when I use
- Swing?
-
- [*] The answer relates to lightweight and heavyweight (peer-based)
- components. There is a good article about it at
- http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html
-
- For those who want the quick fix, and will read the article later,
- adding the line:
-
- com.sun.java.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
-
- before you create any menus will probably fix it (even if you're using
- menus other than JPopupMenu).
-
- The summary answer is that a Lightweight component will not appear over
- a heavyweight component by default.
-
- 8. (Sect. 11) Why is there no JCanvas? How do I get a lightweight Canvas?
-
- [*] Use a JPanel as a Swing replacement for Canvas. All Swing
- components have a paint(Graphics) routine that you can override, just
- as you would have with Canvas, (but you probably want to override
- paintComponent(Graphics) instead, see next question).
-
- 9. (Sect. 11) Why don't the borders of my Swing components look right when
- I override paint(Graphics)?
-
- [*] Swing splits painting into several different routines:
- o paintComponent(Graphics),
- o paintBorder(Graphics),
- o paintChildren(Graphics)
- all of which are called from paint(Graphics). If you override paint(),
- unless you remember to do it, the paintBorder() and paintChildren()
- won't get done.
-
- In most cases, what you really want to do is override paintComponent()
- instead of paint().
-
- 10. (Sect. 11) Why does my JFrame go away after I choose system close on
- the window?
-
- [*] Assume that you have a Swing JFrame component, and you handle the
- windowClosing event, but do nothing in the handler. You will see that
- the JFrame disappears anyway.
- The reason is that JFrame's have default handling of the system close
- operation, separate from the windowClosing event. You have to override
- that by calling:
-
- setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-
- on your JFrame.
-
- 11. (Sect. 11) Why can I run the Mac Look and Feel only on Mac OS?
-
- [*] (This answer comes from the Swing Connection, see
- http://java.sun.com/products/jfc/tsc/swingdoc-current/911.html).
- Sun has not determined that it has the right to deliver the Mac look
- and feel on platforms other than MacOS. If Apple were to confirm Sun's
- right to deliver this look and feel on other operating systems, Sun
- would be delighted to remove the lock. To date, Apple has declined to
- do this.
-
- Although you cannot use the new Mac L&F on non-Macintosh platforms,
- there is a way to examine the source code so developers can use it as
- an example of how to create a custom L&F. The Mac L&F is distributed in
- "stuffed-binhexed" format, which is standard for the Macintosh. If you
- develop on a MS-Windows platform and would like to examine the source
- code for the Mac L&F then you can do that by downloading and using a
- program called Aladdin Expander for Windows. You can download Aladdin
- Expander from this URL: http://www.aladdinsys.com/expander/index.html
- When you have downloaded Aladdin Expander, you can use it to decode the
- Mac L&F file posted on the JDC.
-
- A recent posting on comp.lang.java.gui suggested the following user
- workaround:
-
- import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
- class MyOwnWindowsLookAndFeel extends WindowsLookAndFeel {
- public isSupportedLookAndFeel() { return true; }
- }
-
- The desire on Sun's part to avoid infringing the Windows Look and Feel
- is also the reason why the JTree uses colored circles (and soon, little
- circles with a short line coming out of them) for the nodes to indicate
- whether they are open or not. The Swing team could have used the '+'
- and '-' as Windows does, or even the triangles that MacOS uses, but
- decided against it.
-
- -------------------------------
-
- 12. Browsers
-
- 1. (Sect. 12) When will my favorite browser support Java 1.1?
-
- [*] All popular browsers now have JDK 1.1 support. Netscape
- Communicator 4.04 plus patch "J" fully supports the features of Java
- 1.1. It was released in December 1997, and is only missing the JavaSoft
- support for applet signing (Netscape has gone its own way on this). See
- http://developer.netscape.com/support/faqs/champions/java.html#21
- If you have Netscape 4.05, and the console says anything other than
- Java 1.1.5 then you do not have a fully 1.1 compliant Netscape. There
- is a special preview version available here:
- http://developer.netscape.com/software/jdk/download.html
-
- Netscape badly fumbled its Java support in 1997 as its market was
- seized by Microsoft. Microsoft is using IE as a strategic tool to
- deploy what Microsoft employees call "polluted Java". For both of these
- browsers, the Java Plug-in is a good approach.
-
- Sun's HotJava browser fully supports the JDK 1.1 features. People who
- are obliged to use a browser without standard Java support should use
- the Java Plug-In. The Java Plug-In substitutes a standard Java virtual
- machine for the one that shipped with the browser. It allows you to use
- RMI, JavaBeans components, and Java Foundation Classes in Internet
- Explorer 3.02, 4.0, and 4.01. The Java Plug-In also works flawlessly
- with Netscape browsers. You can download the Java Plug-In from
- http://java.sun.com/products/.
- Note that you need to change the HTML a little, to ensure that the
- plug-in JVM is invoked, not the browser JVM. A tool is included to do
- the changes automatically.
-
- 2. (Sect. 12) What applet routines get called in various browsers and the
- plug-in on different browsing actions (back, forward, load, etc)?
-
- [*] Java supporter Dave Postill did the work to get this answer.
- The life cycle of an applet is illustrated by logging calls to init(),
- start(), stop() and destroy(). Use caution when your applets have
- threads since in most sample applet code, the stop() method calls stop
- on any separate threads within the applet, and then sets them to null.
-
- This reckless threadicide is because most people think of the stop()
- method as something called only when the user leaves the page and wants
- to forget about it. But since Netscape calls stop() when you resize the
- window, your users would lose the applet's state when they thought they
- were only making a minor adjustment.
-
- See "Java Tip 8: Threads, Netscape, and the resize problem - How to
- deal with applet resizing in Netscape Navigator", JavaWorld
- http://www.javaworld.com/javatips/jw-javatip8.html. Sadly the JavaWorld
- workaround does not completely fix the problem, since it relies on
- start() being called soon after stop() to identify a resize. However if
- you minimise the browser it may send a stop() to the Applet and then
- may not send a start() until the Browser is either restored or
- maximised. In this case, using the workaround results in the Applet
- being destroyed following minimising of the Browser - unless the
- Browser gets un-minimised within the killThreads timeout.
-
- Netscape Netscape Applet- Internet Internet
- [4.04/JDK with Viewer Explorer 4 Explorer
- 1.1.4] Plug-In [JDK SP1 with Plug-In
- [4.05/JDK [4.05/ JDK 1.1.5] 4.72.3110.8 [5.00.0518.10
- 1.1.5] 1.1.5/ [JDK on NT 4.0 / Plugin 1.1]
- Plugin 1.1] 1.1.6] SP3 on NT 4.0 SP3
- 1. Clear
- browser nothing nothing nothing nothing nothing
- cache
- init(),
- 2. start() or
- Initial init(), init(), init(), init(), init(),
- load of start(), start() start() start() start()
- .html stop(),
- start() [1]
-
- 3. Back stop() stop(), [4] stop(), stop(),
- destroy() destroy() destroy()
- 4. init(), init(), init(),
- Forward start() start() [4] start() start()
- stop(), stop(), stop(), stop(),
- init(), init(), init(), init(),
- start() start() start() start()
- 6.
- <shift>
- reload stop(), stop(), stop(), stop(),
- [NS], destroy(), destroy(), [4] destroy(), destroy(),
- <ctrl> init(), init(), init(), init(),
- reload start() start() start() start()
- [IE]
-
- 7. Resizestop(), [3] [3] [3] [3]
- start()
- 8.
- Minimize [2] [3] stop() [2] [3]
- 9.
- Restore [2] [3] start() [2] [3]
-
- 10. Exit stop(), stop(), stop(), stop(), stop(),
- destroy() destroy() destroy() destroy() destroy()
-
- Notes:
- [1] Results not repeatable.
- [2] Not tested.
- [3] Tested, and found that no logged methods are called.
- [4] Test not applicable.
-
- 3. (Sect. 12) Is it possible to set and retrieve cookies from Java, in a
- manner that is compatible with all browsers supporting cookies?
-
- [*] Short answer: no.
- Longer answer: probably no.
- Ultimate answer:
- A cookie is a morsel of tasty data that a server sends back to the
- client, and can retrieve on demand. It allows the server to retain some
- state information for each of its clients. The information is typically
- something like "what pages has the user seen?" or "is this a privileged
- user?".
- The DevEdge site on Netscape's home page has a Javascript-Java example
- on getting cookies. Also
- http://www.geocities.com/SiliconValley/Vista/1337 has info on
- connecting an applet with JavaScript functions. It's quite involved.
- Stick to just Java if you can.
-
- 4. (Sect. 12) I am developing an applet and testing it in Netscape
- Navigator. I find that after I recompile, I press reload, clear the
- caches, retype the URL of the HTML wrapper, and I still have the old
- version. Why is this?
-
- [*] It is because Netscape has completely failed to improve the
- defective code that does this monstrously wrong thing. It has been like
- this for many successive releases.
- Flushing the network cache will make no difference; that isn't where
- the caching is taking place. Although applets are sometimes "pruned"
- and their ClassLoaders garbage-collected, this doesn't happen
- predictably, so restarting Netscape is the only reliable work-around at
- the moment.
- A related question is "how do I make the browser reload from a
- URLConnection instead of just getting the content from the local
- cache?" The answer is to use
-
- java.net.URLConnection.setUseCaches(false)
-
- Browsers seem to vary in their conformance to this programmatic
- request. Netscape caching varies depending on whether a proxy server is
- in use, and which thread in the applet made the get request.
-
- 5. (Sect. 12) Why can't Netscape reload the applet when you press the
- Reload button?
-
- [*] For the applet to be reloaded, the new version would have to be
- loaded in a different ClassLoader. Navigator/Communicator's policy for
- assigning ClassLoaders to applets doesn't take into account whether a
- reload has been done (although there is no technical reason why it
- couldn't).
- Some versions of Netscape reload the Applet if you use
- Edit/Preferences/Advanced/Cache to Clear Memory Cache and Clear Disk
- Cache, then <Shift> while you click on reload.
- In Explorer, use View/Options/General/Delete Files, then <Control>
- 'Reload' button to reload the page containing the applet.
-
- Until they fix it, use the appletviewer to test applets. And send them
- mail - developers can only fix the bugs they know about.
-
- 6. (Sect. 12) Should I use Microsoft CAB files or Java JAR files?
-
- [*] The question contains its own answer.
- CAB format is a Microsoft-only format. So do not use it as it destroys
- software portability.
- JAR format is the Java standard format, based on PKZIP format including
- data compression. JARs were introduced with JDK 1.1.
- See http://www.ibm.com/java/community/viewarchive4.html for more
- information.
- You should use the Java standard format JAR (Java Archive) files, not a
- vendor-specific format. JAR files are not just a Java standard, they
- are in industry-standard PKZIP format. One reader comments that both
- formats can be used with this tag:
- <APPLET NAME=myapplet
- ARCHIVE="myzip.zip"
- CODE="com/nnnnn/nnnn/cccccccc.class"
- WIDTH=n
- HEIGHT=n>
- <PARAM NAME="cabbase" VALUE="mycab.cab">
- </APPLET>
- IE3 does not support JAR
- IE4 supports compressed and uncompressed JAR, but not signed JAR
-
- 7. (Sect. 12) How can I tell the version of Java that my browser supports?
-
- [*] See http://java.rrzn.uni-hannover.de/insel/beispiele/vertest.html.
- This page tells you whether your browser supports JDK 1.1.
-
- See http://www.uni-kassel.de/~pfuetz/Properties.html This page tells
- you which classes you may expect to be present in the browser's
- runtime.
-
- -------------------------------
-
- 13. Applets
-
- 1. (Sect. 13) What is the difference between an application, an applet,
- and a servlet?
-
- [*] An application is a standalone program. An applet is a downloadable
- program that runs in a web browser. Typically an applet has restricted
- access to the client system for reasons of security. Other than that it
- is virtually no different from a regular Java program.
- A servlet is a Java program whose input comes from a server and whose
- output goes to a server. Other than that it is virtually no different
- from a regular Java program. Think of a servlet as an application, but
- one that (like an applet) requires a context in which to run, namely
- web server software. Servlets are used like CGI scripts, and they allow
- the server end to be written in Java as well as the client. There is a
- page with much servlet information at:
- http://www.frontiernet.net/~imaging/servlets_intro.html
- There is a servlet tutorial at
- http://java.sun.com/docs/books/tutorial/servlets/index.html
- The web server starts up a servlet when the URL is referenced, and now
- your applets have something that they can talk to (via sockets) on the
- server that can write files, open connections to other servers, or
- whatever.
- There is also a software technology from IBM called an "Aglet". An
- aglet is a mobile agent that can go from machine to machine, performing
- tasks, serializing data collected, and "shipping itself" (code and
- data) to the next machine. It's too early to say if aglets are a flash
- in the pan or a dawning technology. Read about aglets at
- http://www.trl.ibm.co.jp/aglets/
- Finally, there is the ticklet (Tcl/Tk) plugin for your browser
- (Netscape or Explorer) available at http://sunscript.sun.com/plugin/
- Don't confuse Sun's JWS "Java Web Server" with JWS "Java Workshop".
- Java Web Server supports servlets, as does the lightweight and free
- server at Acme.com:
- http://www.acme.com/java/software/Acme.Serve.Serve.html
-
- 2. (Sect. 13) My applet works on my machine, but fails when I put it on
- our web server. Why?
-
- [*] It could be one of several reasons, and unfortunately the messages
- that you get in this situation aren't much help. In general, you can
- assume that either your applet's class files are corrupted somehow, or
- the web server can't find one or more of them when the browser needs
- them.
- Be careful of the following things:
- o Make sure you transfer the class files in binary mode, rather than
- text or ASCII mode. An error from the browser saying "cannot start
- applet ... bad magic number" usually means that one of the class
- files on the server is corrupted. Replace your class binary files
- on the web server, clean up the cache of your browser, and reload
- your applet.
- o Make sure you transfer all of the class files that are a part of
- your applet. Sometimes people are surprised by how many there are.
- There will be a class file for every class and interface you
- define, even if you define more than one in a single source file.
- If you use the Java 1.1 "inner classes" feature, there will be
- class files for each inner class as well.
- o Make sure you maintain the appropriate case distinctions in your
- filenames. If a class is called StUdLy, it must be found in a file
- called StUdLy.class.
- o Make sure you maintain the directory structure that matches your
- package structure. If you declare a class in package com.foo.util,
- the class either needs to be in a Jar file, or the class file
- needs to be in directory com/foo/util under the applet's codebase
- directory. Again, case distinctions are important for
- package/directory names, just as they are for class/file names.
- o Make sure that the web server process will have read access to the
- class files, and search access to the directories that the files
- are in. For example, if the web server runs on a Unix machine, use
- the command "chmod o+r filename" for the files, and "chmod o+x
- dirname" for the directories.
-
- 3. (Sect. 13) How do I load a webpage using an applet?
-
- [*] Use code like this,
-
- getAppletContext().showDocument(
- new URL("http://www.here.com") );
-
- Or, to show the page in another window or frame,
-
- getAppletContext().showDocument(
- new URL("http://www.here.com"), "windowname" );
-
- 4. (Sect. 13) How do I use an image as the background to my applet? How do
- I set the background color of my applet the same as the browser?
-
- [*] You can simply do a g.drawImage(yourImage, x, y, this) in the
- paint() routine of your applet. If the image isn't big enough to fill
- the entire background, tile it or scale it. Here is some code to tile
- it
-
- // The background image is named "bg".
- int w = 0, h = 0;
- while (w < size().width) {
- g.drawImage(bg, w, h, this);
- while ((h + bg.getHeight(this)) < size().height) {
- h += bg.getHeight(this);
- g.drawImage(bg, w, h, this);
- }
- h = 0;
- w += bg.getWidth(this);
- }
-
- Alternatively, the AWT can scale your background image to the size of
- the applet. The result quality will depend on the kind of image. Inside
- an applet class, you can use:
-
- drawImage(img, 0, 0, size().width, size().height, this);
-
- You can set the background color to match the background color of the
- browser by passing the value in as a parameter, like this:
- In the HTML applet tag:
- <param name=BrowserColor value=F1F1F1>
- (value should be the same hex as the HTML COLOR value).
- In the Applet init() method:
-
- String colparam = getParameter("BrowserColor");
- int col = Integer.valueOf(colparam,16).intValue();
- setBackground( new Color(col) );
-
- An applet cannot override the size imposed by the HTML. If you make the
- applet larger, the browser will still clip to the original size. If you
- need more room, open up a new Frame, Window or Dialog to show your
- output.
-
- 5. (Sect. 13) How do you make the applet's background transparent?
-
- [*] There is no way to give an applet a transparent background that
- lets the web browser background show through. You can simulate it by
- giving the applet a background that matches the underlying browser
- background. It doesn't produce satisfactory results with a patterned
- background because of problems aligning the edges.
- Lightweight components (new in JDK 1.1) have a transparent background,
- but that merely allows other components to show through. A lightweight
- component is always ultimately positioned in a heavyweight component.
-
- 6. (Sect. 13) How do you do file I/O from an applet?
-
- [*] See answer to question 7.8.
-
- 7. (Sect. 13) How do you get a Menubar/Menu in an applet?
-
- [*] In your applet's init() method, create a Frame instance and then
- attach the Menus, Menubar etc to that frame. You cannot attach the Menu
- or a Menubar to an applet directly.
- Or get the parent Frame like this (doesn't work in all execution
- environments):
-
- Container parent = getParent();
- while (! (parent instanceof Frame) )
- parent = parent.getParent();
- Frame theFrame = (Frame) parent;
-
- This second suggestion definitely doesn't work in the appletviewer, and
- probably won't work on Macs (where would the Menubar go?) or in some
- browsers. In JDK 1.1, just use a popup menu, which isn't attached to a
- Frame.
-
- 8. (Sect. 13) Can I get rid of the message "Warning:Applet Window" along
- the bottom of my popup windows in my Applet?
-
- [*] This is a security feature that prevents the applet programmer from
- popping up a window that looks like it came from the native OS and
- asking for passwords or credit card info (etc.). Users must always be
- aware of when they are talking to an unsigned applet. You can get rid
- of it by signing the applet, if the user accepts signed applets from
- you. See the Java Signing FAQ at
- http://www.fastlane.net/~tlandry/javafaq.txt
- In Netscape (only), using the Capabilities API to make the call
-
- PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
-
- before creating the Frame eliminates the message, if the security
- manager passes it.
-
- 9. (Sect. 13) When I subclass Applet, why should I put setup code in the
- init() method? Why not just a constructor for my class?
-
- [*] The browser invokes your constructor, then setStub, then init().
- Hence when your constructor is invoked, the AppletStub (and through it
- the AppletContext) is not yet available. Although in principle you can
- do things in the constructor that don't rely (even indirectly) on the
- AppletStub or AppletContext, it is less error-prone to simply defer all
- setup to the init() method. That way you know that anything that needs
- the stub/context will have it available.
-
- 10. (Sect. 13) How do I pull a non-class file, such as a .gif, out of a jar
- file?
-
- [*] In your class, you should be able to do something like this:
-
- String imageFileName = "foo.jpg"
- URL imageURL = getClass().getResource(imageFileName);
- Toolkit tk = Toolkit.getDefaultToolkit();
- Image img = null;
- try {
- java.awt.image.ImageProducer I_P;
- I_P = (java.awt.image.ImageProducer)imageURL.getContent();
- img = tk.createImage(I_P);
-
- Or equivalently, and possibly simpler, this:
-
- String imageFileName = "foo.jpg";
- InputStream jpgStream = getClass().getResourceAsStream(imageFileName);
- Toolkit tk = Toolkit.getDefaultToolkit();
- Image img = null;
- try {
- byte imageBytes[]=new byte[jpgStream.available()];
- jpgStream.read(imageBytes);
- img = tk.createImage(imageBytes);
-
- (Like anything involving Jar files, this is from JDK 1.1 on.)
- getResource(String) does not work in applets in Netscape
- due to Netscape security issues. You should use
- getResourceAsStream(String) there instead.
- See http://developer.netscape.com/software/jdk/relnotes.htm
-
- Note that getResourceAsStream() is also good for reading a text (or
- other kind of) file from a JAR file.
-
- public void init() {
- InputStream myStream = getClass().getResourceAsStream("myFile");
- // ...
- }
-
- Once you have it as an InputStream you can read it how you like.
-
- 11. (Sect. 13) I want to know about {applets,applications} but the lousy
- book I got just talks about {applications,applets}. What can I do?
-
- [*] The truth is that 95% of the material is the same, whichever your
- book chooses to focus on. Some people write their apps to work
- completely in a Panel, then depending on whether they're running
- stand-alone or in a browser the Panel is either added to a Frame or an
- Applet. The trick is that you need to add a listener to the
- application's Frame to handle the WINDOW_CLOSING (previously
- WINDOW_DESTROY) event yourself.
- If you fail to do this, when running as an application, the window
- won't close. See Question 15.7 for a sample of the right handler.
- In this scenario the following code will tell you which environment
- you're running in:
-
- public boolean isRunningInBrowser() {
- Component p = getParent();
- while(p != null && !(p instanceof Frame)) {
- p = p.getParent();
- }
- return (p == null);
- }
-
- 12. (Sect. 13) How do I print a page with an applet?
-
- [*] Browsers are starting to introduce support for this. Until they all
- have it, your best bet is to print a screendump. Using the browser to
- print the page may leave a blank where the applet is. Putting print
- support in the applet will print the applet only, not the rest of the
- browser page.
- Also in the FAQ: Q5.2.
-
- 13. (Sect. 13) How can I position my dialogs centered (not top left)?
-
- [*] Use some code like this:
-
- void center(Component parent) {
- pack();
- Point p = parent.getLocation();
- Dimension d = parent.getSize();
- Dimension s = getSize();
- p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
- setLocation(p);
- }
-
- 14. (Sect. 13) How can I get two applets on the same page to communicate
- with each other?
-
- [*] This is the purpose of the InfoBus protocol. See
- http://java.sun.com/beans/infobus/index.html
-
- The older way to do it was as follows. In your HTML page, give a NAME
- in the APPLET tag for the applet receiving the message, say <APPLET ...
- NAME=someName ...>. In the Java code of the other applet do
-
- Applet anotherApplet = getAppletContext.getApplet("someName");
-
- Cast anotherApplet to the correct applet subclass, and you can call any
- methods in the applet subclass. Don't forget to use appropriate
- synchronization when two threads tweak variables. This only works when
- the applets are truly on the same page. If they are in different
- frames, it doesn't work.
- You can walk through all the applets on an HTML page using code like
- that below. However this appears to be broken in Communicator 4.04 on
- Win95.
-
- Applet otherApplet;
- AppletContext ac =getAppletContext;
- Enumeration applets = null;
- for (applets=ac.getApplets(); applets.hasMoreElements(); ) {
- otherApplet=(Applet)applets.nextElement();
- if (otherApplet!=this) break;
- // do something with otherApplet, e.g.
- // if (otherApplet instanceof FooApplet) ...
- }
-
- Some people suggest using the static members of a common class to
- communicate information between the applets. This is not recommended as
- it relies on class-loading behavior that may change in future. Netscape
- changed it in one Beta so it didn't work, then changed it back again so
- it did. It doesn't work if you use the "mayscript" tag though.
- Inter-applet communication sometimes arises when you have a
- multi-screen type program and you don't want to force the user into
- downloading everything at once. One alternative is to make them into
- one applet with two GUIs. Try to avoid the need for applets to talk to
- each other. Also check the URL
- http://java.sun.com:81/products/hotjava/1.1/applet_environment.html
- which explains how it can be done in HotJava 1.1. Recommendation: avoid
- code which is browser-specific.
-
- 15. (Sect. 12) How can I resize an applet?
-
- [*] If you want resizing behavior from an applet, you should launch an
- external Frame that can be resized independently.
- One programmer suggests using percentages for the height/width
- parameters in an applet tag, like this:
-
- <APPLET CODE="lewinsky.class" WIDTH="100%" HEIGHT="100%">
-
-
- You can't resize the applet directly, but it does get resized when you
- resize the browser window (tested with Netscape 3.04 and 4.04, but does
- not work with appletviewer). If you have nothing else on your HTML page
- and use 100% for your width and height, the browser window looks almost
- like a real application.
- For the extremely tricky: have the browser reload the page with the
- applet when the browser resizes using new values for width and height
- (probably not what you want most of the time). You would need
- Javascript to generate a page dynamically using document.write("...")
- when the browser resizes. Not recommended. Another possibility is to
- use the new SplitPane class in JFC.
-
- 16. (Sect. 13) How do I read a text file stored in a JAR?
-
- [*] The best way to do this is to use the method
- Class.getResourceAsStream() which will give you an input stream from
- which you can read the text file in the JAR. This technique can be used
- to get parameter info from a text file for an applet.
- Other sites: See http://www.uq.net.au/~zzcmumme for an example.
-
- -------------------------------
-
- 14. Multi-Media
-
- 1. (Sect. 14) Are there any good Java Image libraries?
-
- [*] Yes. Try the Java Image Management Interface (JIMI), which offers a
- free trial period. JIMI is a toolkit that lets your Java programs read
- and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
- written in 100% Java, and best of all, it's a breeze to get started
- with. See http://www.activated.com/jimi.html
-
- 2. (Sect. 14) Why won't my audio file play?
-
- [*] Java 1.1 and earlier releases use one audio format exclusively. The
- audio file must be in .au format, recorded at 8 KHz, mono, in mu-law
- encoding. If your audio clip is in a different format (e.g., .wav) or a
- different frequency it must be converted to the exact specifications
- above before Java can play it. Support for .wav and other formats is
- part of the Java Media Framework coming in JDK 1.2.
- Search at http://www.yahoo.com for GoldWave for Win 95, sox for Unix
- and similar conversion utilities for other systems.
- Other sites:
- o One conversion utility in Java is at
- http://saturn.math.uaa.alaska.edu/~hursha
- o The source of a Java class to play linear PCM .WAV files is at:
- http://www.shef.ac.uk/~cs1mjp/Java/WhiteBoard/WavePlayer.html. It
- can be used in any Java application or applet.
-
- 3. (Sect. 14) How can I do video streaming using Java?
-
- [*] That is the purpose of StreamBean. See
- http://www.streambean.com/streambean/
-
- 4. (Sect. 14) Does Java support animated GIFs?
-
- [*] Java 1.0.2 and earlier releases use GIF and JPEG formats, and do
- not use the GIF89 animated GIF format. (An animated GIF is one that
- contains successive frames of an image, so when they are displayed in
- quick sequence the image appears to contain movement). When you display
- an animated GIF in Java 1.0.2, you will just get the first frame. There
- doesn't appear to be any easy way to get other frames from the image.
- The advantage of an animated GIF file is that there is only one file to
- download, and it is simple to do simple animations. The advantage of
- programmatic control over individual frames is that you control the
- rate and order of displaying them.
- Here's a surprise: JDK 1.1 supports the animated display of animated
- GIFs. For simple animations animated GIFs are a lot easier and
- lighter-weight than coding an animation explicitly.
-
- 5. (Sect. 14) How do I create animated GIFs?
-
- [*] Use GIFanimator from ULead (said to be the best)
- http://www.ulead.com, or GIF Construction Set from Alchemy Mindworks
-
- 6. (Sect. 14) How do I prevent animated GIFs from flashing while
- displaying?
-
- [*] The problem is most likely that in your paint method you have
-
- g.drawImage(img, ix, iy, this);
-
-
- You should change this to
-
- g.drawImage(img, ix, iy, getBackground(), this);
-
-
- This will change all the transparent regions of the image to the
- background color before painting to the screen. If you paint
- transparent images directly to the screen they flicker.
- If that does not solve it then check that imageUpdate is
-
- public boolean imageUpdate(Image img, int flags, int x, int y,
- int width, int height) {
- if ((flags & (FRAMEBITS|ALLBITS))!= 0) repaint();
- return (flags & (ALLBITS|ABORT)) == 0;
- }
-
-
- update is
-
- public void update(Graphics g) { paint(g); }
-
-
- If you have a background Image behind the partly transparent animated
- GIF you will have to double buffer. You can crop the backgound image so
- you won't have to double buffer the full app and waste too much memory.
-
- 7. (Sect. 14) Does Java support transparent GIFs?
-
- GIF89a images with a transparent background show up as transparent
- without further filtering. This has been supported from 1.0 on. Java
- correctly displays both animated GIFs and transparent GIFs.
- Even better, you can fill the transparent pixels with a color (so they
- appear non-transparent in Java). Just pass the fill color explicitly:
-
- drawImage(img, x, y, w, h, fillcolor, this);
-
-
- Further, you can filter the pixels of an Image to turn any bits you
- wish transparent. However, the most you can do is reveal what is
- underneath the image. You cannot reveal what is underneath the applet
- (i.e. on the browser itself). By default applets have a plain grey
- background.
-
- 8. (Sect. 14) How do I play video in Java?
-
- [*] Use the Java Media Framework Player API.
- Other sites:
- o The Java Media Framework Player API spec can be found at
- http://java.sun.com/products/java-media/jmf/
- o Intel has released a SDK for the Java Media Framework Player API.
- The SDK is for Windows 95 and Windows NT. For more information,
- see http://developer.intel.com/ial/jmedia
- o SGI has released an implementation of JMF for IRIX: See
- http://www.sgi.com/Products/motion/
-
- 9. (Sect. 14) How can I play *.au files from an application?
-
- [*] A new static method was introduced in JDK1.2 in the class Applet:
-
- public final static AudioClip newAudioClip(URL url) {
-
-
- The method turns a URL (pointing to an audio file) into an AudioClip.
- Since the method is static it can be used without any objects of class
- Applet needing to exist, e.g. in an application. Once you have an
- AudioClip, you can play it with:
-
- MyAudioClip.play();
-
-
- The Java Media Framework provides a richer API for playing sounds in an
- application.
- For code prior to JDK 1.2, you can use the AudioClip or AudioPlayer
- class in sun.audio
- http://www.javaworld.com/javaworld/javatips/jw-javatip24.html. If you
- do this your code is no longer 100% pure Java, as it relies on a vendor
- library.
-
- import sun.audio.*;
-
-
- URL url; ...
- AudioStream audiostream = new AudioStream(url.openStream());
- AudioPlayer.player.start(audiostream);
- ...
- AudioPlayer.player.stop(audiostream);
-
-
- Also in the FAQ:
- Use the new Java Media Framework API, allowing a wide range of video
- and audio formats to be played back. See previous question.
-
- 10. (Sect. 14) How do I read in an image file, in an application?
-
- Use
-
- Image img = Toolkit.getDefaultToolkit().getImage(fname);
-
-
- 11. (Sect. 14) When I initialize a component,I call MyComponent.getImage()
- to get its image. createImage() returns null! I know the image works
- elsewhere. What's wrong?
-
- [*] A peer component needs to exist for your component before you can
- get its image. This is done by the method addNotify() (surely one of
- the most poorly named methods in all Java -- it doesn't mean "add a
- Notify". It means "Notify that the Component has been added to a
- Container". It tells the system, "you need to create the peer for this
- Component now"). addNotify will be called for you when you add your
- component to a container.
- Javasoft notes that most applications do not call addNotify() directly.
- It is called for you when you add the component to a container. If you
- have any code that requires peer resources, you can move it into a
- thread that is started from a conditional branch of the paint() or
- update() method. That way the peer will definitely exist when the code
- is executed.
- A common reason for seeming to require peer resources in a constructor,
- or alternatively in the getPreferredSize() method, (which is also
- usually before the peer is created) is to measure the area required for
- your window, in terms of font and image sizes. Font sizes may be
- obtained by calling
- Toolkit.getDefaultToolkit().getFontMetrics(somefont). This does not
- require a peer. Image sizes may be obtained by waiting for the relevant
- Image to load from the ImageProducer by using an ImageObserver, or a
- MediaTracker (see 8.15), also without requiring a peer. See 15.4 for
- more discussion of this problem.
- If you override addNotify(), don't forget to call super.addNotify() in
- your overriding version.
-
- 12. (Sect. 14) How can I force a reload a fresh version of an image into my
- applet? My image file is changed periodically, and I want the applet to
- go and retrieve it, not cache it.
-
- [*] You need to turn off caching for the URL.
-
- URL url = null;
- URLConnection con;
- try {
- url = new URL(getDocumentBase(),"image.jpg");
- con = url.openConnection();
- con.setUseCaches(false);
- } catch (MalformedURLException e1) {
- System.err.println(e1.getMessage());}
- catch (IOException e2) {
- System.err.println(e2.getMessage());}
-
- Note: Some programmers have reported that it caches anyway, even if
- they do this. That is a browser bug.
- One programmer reported that even after turning off caching and calling
- image.flush() before getImage(..), he was still seeing the same picture
- even though it had been changed on the server.
- He worked out a solution: access the image via a cgi script that
- returned a URL. This redirects the browser, and he put in an Expires:
- header as well to force the reload. Painful and laborious, but it got
- the result.
-
- 13. (Sect. 14) How can I save an Image file to disk in JPG or GIF format?
-
- [*] A number of people have written utilities to do that. One of them
- was available at the same place as this FAQ, but has now been removed
- since it was pointed out that Unisys asserts that it has license
- control even over freeware GIF writers.
-
- Try the Java Image Management Interface (JIMI), which is free for
- non-commercial use. JIMI is a toolkit that lets your Java programs read
- and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
- written in 100% Java, and best of all, it's a breeze to get started
- with. See http://www.activated.com/jimi.html
-
- Other sites:
- o Jef Poskanzer has written an abstract ImageEncoder class and
- implemented it for GIFs and PPMs. Those are at
- http://www.acme.com/java/software/
- o A non-Java solution is to use the standard IJG 'cjpeg' utility. It
- supports GIF, PPM, BMP, PNG and Targa input files.
- o Hong Shi wrote a PPM to JPEG convertor.
- http://www.ctr.columbia.edu/~hshi/report6880.htm
- o Sean Breslin has written a program that compresses a Java Image
- into a JPEG file. http://www.afu.com/jpeg.txt
- o Florian Raemy has written a program that encodes a JPEG then
- decodes it again. http://lcavwww.epfl.ch/demos/jpeg.html This is a
- proof of concept, not industrial strength code that meets the JFIF
- (JPEG File Interchange Format) standard.
-
- 14. (Sect. 14) What causes this problem:
-
- $ appletviewer m.html
- Premature end of JPEG file
- sun.awt.image.Im...Exception: JPEG datastream contains no image
- at sun.awt.image. ... .produceImage(JPEGImageDecoder.java:133)
- at sun.awt.image.Inpu...mageSource.doFetch(
- InputStreamImageSource.java:215)
- at sun.awt.image.ImageFetcher.run(ImageFetcher.java:98)
-
- [*] There's a known bug in early releases of the JDK which can cause
- the above failure when reading a JPEG across a slow connection. The
- failure only occurs if the JPEG contains a large application data block
- (APPn marker) - the problem is that the JPEG decoder is trying to skip
- over the APPn and failing if not all of the APPn has been received yet.
- The quoted error message is only one of several possible complaints,
- but they all stem from the same root.
- Photoshop is the most common source of JPEGs containing oversize APPn
- blocks. In particular, if you allow Photoshop 4 to save a thumbnail
- (preview) in a JPEG, the thumbnail plumps up Photoshop's private APPn
- marker to several K, which is usually enough to cause this problem.
- There are several possible workarounds:
- o Get a newer JDK - this problem is said to be fixed in 1.1. (If you
- are putting images up on the Web, this isn't much of a solution,
- because you can't assume visitors to your site have an up-to-date
- Java installation.)
- o When making JPEGs for Web use from Photoshop, make sure you have
- turned off the "save thumbnails" preference. (This is a good idea
- quite aside from bug workarounds, because the thumbnail is just a
- waste of download time as far as a Web browser is concerned.) You
- might still have a problem if you've got verbose comments or lots
- of paths being saved into the file, but 99% of the time, getting
- rid of the thumbnail will make Photoshop's APPn small enough to
- not trigger the Java bug.
- o Use a tool such as 'jpegtran' (from the Independent JPEG Group) to
- strip out the Photoshop APPn entirely without any loss of image
- quality. Recommended answer for the compulsive byte-trimmer.
- o (Last resort) Load and resave the image in a different image
- editor that won't insert any APPn or other overhead data. This
- implies a JPEG generational loss, so I don't recommend it if you
- are picky about image quality.
- Any large overhead marker will cause the same problem; 4K of comment
- text, say, in a COM marker. So Photoshop is not the only source of
- tickling this bug.
-
- 15. (Sect. 14) How can I convert between GIF and JPEG formats?
-
- [*] In a word: don't.
- There's hardly any overlap between the set of images that JPEG works
- well on and the set that GIF works well on. Sometimes, with enough
- care, you can get an acceptable conversion...but most of the time
- GIF<->JPEG conversion will just turn your image to mush. It's better to
- pick the right format in the first place.
- Other sites:
- o If you're determined to convert formats anyway, try the GBM
- (Generalized Bitmap Module). The package is GNU licensed, in C and
- is very good. Find it at
- http://www.interalpha.net/customer/nyangau/
- GBM does a good job converting to JPEG, and 'lossiness' is
- adjustable to 0%. It also converts to/from about 20 other formats,
- does cropping, sizing, color mapping, gamma correction,
- halftoning, everything you could want. GBM source doesn't support
- JPEG directly, but utilizes JPEG source from IJG called jpeg-6a
- and found at
- ftp://sun2.urz.uni-heidelberg.de/pub/simtel/graphics/jpegsr6a.zip
- o For more info see the JPEG FAQ at
- http://www.faqs.org/faqs/jpeg-faq/
-
- 16. (Sect. 14) If you have an InputStream (rather than a file) that
- contains an Image, how can you display it?
-
- [*] Use this method, and some adroit shuffling.
-
-
- Toolkit.getImage(URL url)
-
-
- Create a thread that pretends to be an http server. Make it listen to
- some port (8765 for example) for incoming requests. When the thread
- gets a request, it should simply whisk up the appropriate http headers
- and follow it by the InputStream. Thus the component that has the input
- stream and wants to do the getImage(url) can now invoke:
-
- Toolkit.getImage("localhost:8765/")
-
-
- The thread will act as a stream-to-url adapter, and send back the data
- It saves you from having to read 200K of JPEG data before you can begin
- drawing anything.
-
- 17. (Sect. 14) How can I record sounds in Java?
-
- [*] The Java Media Framework will eventually support this, but it does
- not yet. JMF 1.0.1 only supports playback.
- JMF 1.0.1 is bundled with JDK 1.2, and available as a separate download
- for JDK 1.1 and Netscape Communicator 4 with Java 1.1.
- Other sites:
- In the meantime, there is a package for Win95/NT available at
- http://www.scrawl.com/store/. It supports 8, 16-bit, stereo, mono,
- 11025, 22050, 44100 Hz record/play, load/save .WAV files. You
- could also interface to native code for your platform.
-
- 18. (Sect. 14) Does Java have any built-in support for displaying HTML?
-
- [*] JDK 1.1 supports rendering HTML using the unbundled JFC 1.1 package
- known as Swing. The Swing package is bundled in JDK 1.2. It has an
- elementary (graphics, tables, text) HTML bean that is good enough for
- simple rendering (help files, email, etc).
- Other sites:
- o JavaBrowser http://www.ii.uib.no/~alexey/jb/index.html Free
- source, free for use under GNU LGPL licence, HTML 2.0 (sort of).
- o ICE Browser - Java Bean Component
- http://www.icesoft.no/ICEBrowser/ Free binaries for use in free
- applications. Commercial licensing available including source -
- flat fee licence. Thin HTML client! Lightweight! HTML 3.2
- o HotJava HTML Component - Java Bean Component
- http://www.javasoft.com/products/hotjava/bean/index.html $195 for
- private use binary licence. HTML 3.2
- o HTML browser (free source)
- http://barium.tn.tudelft.nl/people/gool/java/html/Html.html
- o Web Window Browser http://www.opencube.com/example_wwb.htm $139 -
- no sources.
- o jHelp ($20-650) http://w3.nai.net/~rvdi/jhelp/jhelp2/jhelp.html
- jHelp is a HTML browser component written in Java, HTML 2.0
-
- 19. (Sect. 14) I loaded an Image file from a JPEG/GIF file using the
- Toolkit/Applet.createImage(URL/String) method, and (the height and
- width are -1 / it will not draw to the screen). What is wrong?
-
- [*] The behaviour of the AWT on creating images in this way is to do
- nothing at all.
- When the image is first drawn using Component.drawImage(), or its size
- is requested, the image begins to load in a different Thread.
- As the image loads, the ImageObserver specified in the
- drawImage()/getHeight() call is periodically notified of the loading
- status of the image, by calls to its imageUpdate() method.
- In the case of Component.drawImage() call, the default behavior of
- Component.imageUpdate() is to schedule *another* repaint() call when
- the image has fully loaded. This means that, in particular the
- following code will not work:
-
- class MyComponent extends Component {
- ...
- public void paint(Graphics g) {
- ImageFilter cropper=new CropImageFilter(0,0,16,16);
- Image cropped_image=createImage(new
- FilteredImageSource(image.getSource(),cropper));
- g.drawImage(image,10,400,this); // this line works
- // this line doesn't -
- g.drawImage(cropped_image,400,15,this);
- }
- }
-
-
- The cropped_image will not be created in time to be painted, and when
- it is finally created, another call will be scheduled to paint, which
- will try to draw another one, etc.
- (Note also that creating objects like this in paint() methods is
- generally a very poor idea in Java, since they are called very
- frequently, and you will strongly offend the garbage collector.
- In order to get round this problem, you may i) add all such Images to a
- MediaTracker, and call the waitForAll() method. ii) implement your own
- ImageObserver interface, and wait for the imageUpdate() method to be
- called with the ALLBITS/FRAMEBITS value. i) is easier, but ii) is
- recommended, since there are reports of MediaTracker not working in
- some environments.
- Also in the FAQ:
- o See also Q13.12
- o See Q6.4 for examples of how to reuse objects.
-
- 20. (Sect. 14) How can I record sound in an applet?
-
- [*] If you are using win95/nt, you could use SoundBite - Audio
- Recording in Applets. See http://www.scrawl.com/store/
- It provides easy access to audio data in arrays:
- short[] left, right;
-
- -------------------------------
-
- 15. Networking and Distributed Objects
-
- RMI Issues
-
- 1. (Sect. 15) Should I use CORBA in preference to RMI? Or DCOM? Or what?
-
- [*] If your distributed programs are all in Java, then RMI provides a
- simpler mechanism that allows the transfer of code, pass-by-value of
- real Java objects, and automatic garbage collection of remote objects.
- If you need to connect to C++ (or other language) systems or you need
- CORBA-specific services, then CORBA is your choice.
- In July 1997, Sun announced that it was aligning RMI to work more
- closely with CORBA. Sun is simply adding an IIOP transport layer to RMI
- to support interoperability with CORBA. Java programs can then use RMI
- to access CORBA-based objects through IIOP, the OMG's CORBA-based
- protocol. This is very good news for those building heterogenous
- Enterprise systems, although it will take some additions to IIOP to
- support the pieces that RMI uses.
- Microsoft spokespeople have tried to promote DCOM by spreading
- misinformation that RMI is changing or being dropped. That is totally
- wrong. The RMI API continues unchanged in its current form. Using DCOM
- would restrict your code to only ever run on Microsoft platforms using
- Intel hardware, and negates the "write once, run anywhere" Java
- philosophy. Non-portable, single vendor code should be avoided.
- Other sites:
- http://www.javaworld.com/javaworld/jw-10-1997/jw-10-corbajava.html
- has a good intro to CORBA in the Java world.
- http://www.objenv.com/cetus has a CORBA/RMI comparison.
-
- 2. (Sect. 15) How do I do RMI into a different domain?"
-
- [*] Similar to the proxy answer in a section below; you must tell the
- program where to find the server. In this case start up the client with
- this commandline option: -Djava.rmi.server.hostname=hostname.domainname
-
- 3. (Sect. 15) RMI seems to have stopped working for me in JDK 1.1. Why is
- this?
-
- [*] The rules for where the client looks for a stub class seem to have
- changed making it necessary to reset your class path on the client
- after starting the RMI registry. In particular, it looks like rmic was
- not updated to the new "don't need $CLASSPATH" convention as the
- compiler was.
- Other sites:
- There are several very good sources available from Sun which cover many
- simple and advanced RMI problems.
- o The documentation, of course:
- http://java.sun.com/products/jdk/1.1/docs/guide/rmi/index.html
- o Dedicated FAQs on RMI and Object Serialization
- http://java.sun.com/products/jdk/rmi/faq.html
- o Mailing list RMI-USERS@JAVASOFT.COM with archive at
- http://chatsubo.javasoft.com/email/rmi-users/ Visit the archive!
-
- 4. (Sect. 15) After a number of RMI client to server connections (55 on my
- system), subsequent RMI clients trying to connect fail. Why?
-
- [*] You are hitting the default limit of 64 open file descriptors. Try
- increasing the limit in your OS.
- In addition there is currently a practical RMI connection limit imposed
- by the scalability of the VM and the performance of object
- serialization. This is addressed in JDK 1.2. The actual number of
- active clients you will be able to support will depend on the workload
- mix you have (i.e. the number of clients, how often they talk to the
- server, and how much work must be done per call).
-
- 5. (Sect. 15) I'm using RMI on Win95, and the Naming.lookup() call is
- taking a long time, even for localhost. How do I fix it?
-
- [*] (See also the first answer in next section below) Try adding a
- definition for the machine in your "hosts" file. Typically, this file
- will be named c:\windows\hosts (if it doesn't exist, there should be a
- file called c:\windows\hosts.sam). The hosts file is searched by your
- TCP/IP stack before it resorts to DNS, so adding an entry in this file
- can speed up your lookups considerably. The hosts file is used to map
- IP addresses to symbolic addresses. To enter the name "localhost" with
- address 127.0.0.1 (the IP loopback address), enter the following line
- in your hosts file. 127.0.0.1 localhost
-
- Windows Networking
-
- 6. (Sect. 15) Why does < Windows RMI/my java debugger/IDE/other> hang for
- a couple of minutes if my Windows PC is not dialed up to the Internet?
-
- [*] Java has networking support built in. When the Java program starts
- the Winsock DLL automatically gets loaded. The first thing this does is
- to try to resolve the fully qualified domain name for your machine
- under the name "localhost". If your system doesn't have this name
- mapped, it will try to query a nameserver on the internet, which is
- typically (on a PC) your dialup ISP. So it either prompts you to
- connect to the ISP, or waits till the attempt times out.
-
- You can probably avoid the Win95 problem by giving your system another
- way to resolve DNS names. Edit the hosts file for your system so that
- localhost and the full domain name are both mentioned. On Windows 95
- systems the hosts file is: %windir%\HOSTS (for example,
- C:\WINDOWS\HOSTS). On Windows NT systems the hosts file is:
- %windir%\System32\DRIVERS\ETC\HOSTS (for example,
- C:\WINNT\System32\DRIVERS\ETC\HOSTS).
- One gotcha under Win95 is that if the last entry in the hosts file is
- not concluded with a carriage-return/line-feed then the hosts file will
- not be read at all. So if my system is called goober.best.com change
- the hosts file from
-
-
- 127.0.0.1 localhost
-
-
- to
-
- 127.0.0.1 goober.best.com localhost
-
-
- Showing more of the file:
-
- # Hosts file
- 127.0.0.1 localhost
- 129.146.77.177 goober
-
-
- Another alternative is to dial up with a PPP connection to your ISP
- whenever you want to run networking programs.
-
- Fundamentally the experience of some people has been that networking is
- not completely satisfactory on Windows95, and is subject to sporadic
- unexplained failures. If this occurs to you, there is little choice but
- to reboot and start again.
- Other sites:
- Microsoft has several network-related patches at its site
- http://www.microsoft.com/
-
- 7. (Sect. 15) I am using JDK 1.1.1 on Windows95, and when I start jdb I
- get "Uncaught exception: java.lang.UnsatisfiedLinkError no winawt in
- shared library path". The same program works OK using JDK 1.1.
-
- [*] It sounds like your java\bin directory is not on your PATH and so
- the system can't find the winawt DLL.
- But actually the problem is the version of Microsoft's Visual C++ that
- was used to build the product. VC++ 4.2 incorrectly generates code that
- depends on MSCVRT.DLL or in the case of java_g, MSVCRTD.DLL. These DLLs
- are not present in (some versions of) Win95. To make things even more
- interesting, some versions of Win95 (yes, there are at least four
- different ones...) ship with a broken MSVCRT.DLL (and MSVCRTD.DLL?)
- that seems to work, only it doesn't, and after a while it dies.
- Sun linked the winawt_g.dll with VC++ 4.2, which wrongly brought in
- MSVCRTD.DLL, the debug version of the VC++ runtime. You have to get
- that library from somewhere (like, say, VC++) in order to get jdb to
- run.
- You'll hit this problem any time you try to debug 1.1.1 code with jdb
- on a win95 system that doesn't have VC++ (or the MSVCRTD.DLL library
- from some other source) installed. At least this is a problem you can
- solve without waiting for the next release.
- Other sites:
- Some people say that the missing library has been seen at
- http://cag-www.lcs.mit.edu/curl/Binaries/PC/ Others say you need
- to buy VC++ to get it.
-
- Other Networking Issues
-
- 8. (Sect. 15) If I call the InetAddress.getByName() method with an
- IP-address-string argument, like "192.168.0.1", get an
- UnknownHostException on some platforms, but not others. Code like
-
- Socket sock = new Socket("155.152.5.1", 23);
-
- triggers the exception. Why?
-
- [*] This is a platform difference that arises out of different
- semantics in the underlying network libraries, and is [said to be, but
- subject to confirmation] fixed in JDK 1.1. On Solaris and Windows NT,
- the IP address string only works for IP addresses that have an
- associated hostname. On Linux and Windows 95, the IP address string
- works in all cases.
- When InetAddress is instantiated with an IP address, a reverse DNS
- lookup is done. If the IP address is not associated with a valid
- hostname, the instantiation will fail. This is part of anti
- DNS-spoofing, and in JDK 1.1 works because the reverse lookup will not
- occur until the hostname is asked for. So in JDK 1.1,
-
- InetAddress in = InetAddress.getByName("155.152.5.1");
-
-
- [Note: this info is still to be confirmed. Net gurus?]
- Other sites:
- Microsoft has several network-related patches at its site
- http://www.microsoft.com/
-
- 9. (Sect. 15) I want to pass a class file to willing recipients who are
- using my applet. Any ideas how?
-
- [*] You could use a trick: put your .class file(s) in a .zip archive
- and use showDocument() on the URL. A person accessing this will get a
- dialog box put up asking them about saving the file to their local hard
- disk.
- Other sites:
- You can see this in action and try it out yourself at:
- http://www.best.com/~rmlynch/saveit.html
-
- 10. (Sect. 15) How do I get a URLConnection to work through proxy
- firewalls? I.e. How do you get your Java application to do its web
- accesses through a proxy?
-
- [*] This is typically needed for any net access to another domain. Tell
- the run time system what you are trying to do, by using these
- commandline arguments when you start the program.
-
- java -DproxySet=true -DproxyHost=SOMEHOST -DproxyPort=SOMENUM code.java
-
- Note proxyPort is optional and it defaults to 80. Without this, you
- will see an exception like java.net.UnknownHostException or
- java.net.NoRouteToHostException
-
- [It is claimed but not yet confirmed by me that] The proxy settings
- work for both java.net.URLConnection, and for java.net.Sockets. [help
- welcome].
-
- Netscape's and IE's JVMs (at least in versions 4.x+) take the proxy
- settings for applets from the browser's proxy configuration. You can
- also do URL proxies in applications (not applets) with the following
- code
-
-
- // set up to use proxy
- System.getProperties().put("proxySet", "true");
- System.getProperties().put("proxyHost", "myproxy.server.name");
- System.getProperties().put("proxyPort", "80");
-
-
- But how do I know the name of the proxy server?
- This code just tells you how you can get a URL connection to the
- outside. Since it is your proxy server, you are expected to know the
- name of it. There isn't any code that you can write that will allow
- arbitrary URL connections to be initiated from outside the firewall.
- Think about it! If there were, the firewall would not be doing its job.
-
- Also note there are corresponding socksProxyPort and socksProxyHost for
- when socks is used instead of proxy. The default socks port is 1080.
-
- 11. (Sect. 15) What is "swizzle", as in "Swizzle this object?"
-
- [*] It means serialize. To swizzle an object is to recursively
- serialize or flatten composed objects.
-
- 12. (Sect. 15) I have been using the Serializing capabilities in 1.1 to
- save some objects to disk. I added a new field to one of my objects
- that get serialized and now deserializing my old data no longer works.
- I get this exception:
-
-
- java.io.InvalidClassException: MacroData; Local class not compatible
-
-
- [*] You need to add a declaration such as
-
-
- static final long serialVersionUID = 4021215565287364875L;
-
-
- in the modified class. The actual value of this long is supplied by the
- "serialver" utilitity suppied with the JDK. Any versions of a class
- other than the first version require this static to be defined in the
- class. This is how versioning is achieved.
-
- 13. (Sect. 15) My socket code looks good, but is broken!
-
- [*] When using sockets you typically open both inward and outward
- streams. If you close one of them, the other seems to 'break'
- instantly. Check whether this is happening for you, by adding the
- matched pair.
- [comments from net gurus welcome]
-
- 14. (Sect. 15) How do I map between IP address and hostname?
-
- [*] In Java 1.1 (earlier releases were buggy) use:
-
-
- String host = InetAddress.getByName("211.10.2.119").getHostName();
-
-
- 15. (Sect. 15) How do I embed an anchor in a URL? Just putting it as part
- of the string in the constructor doesn't work.
-
- [*] Like this:
-
-
- URL url = new URL("http://www.my_domain.com/my_page.html");
- URL anchor = new URL(url, "#section2");
- this.getAppletContext().showDocument(anchor);
-
-
- 16. (Sect. 15) How do I POST to a CGI script from an applet?
-
- [*] Let's start by noting that this is more troublesome than it might
- seem at first, and that GET is preferred. For an untrusted applet, the
- CGI script can only be on the server that served the applet. Then use
- code like this:
-
-
- try { sock = new Socket(host, 80);
- dock = new DataOutputStream(sock.getOutputStream());
- dock.writeBytes("POST "+cgiloc+" HTTP/1.0\n");
- dock.writeBytes("Content-type: text/html\n");
- dock.writeBytes("Content-length: " +my_string.length() + "\n\n");
- dock.writeBytes(my_string+"\n");
- dock.close();
- sock.close();
-
-
- uresp = new URL(getDocumentBase(),"respond.html");
- getAppletContext().showDocument(uresp); }
-
-
- The my_string contains the data you want to POST to the CGI script. The
- string should be encoded in the special way CGI expects. The class
- method java.net.URLEncoder.encode(my_string) will do it. The CGI has to
- write its output to respond.html so that it can be displayed by the
- browser. Even this won't really work, because respond.html could be
- overwritten by a subsequent request to the same CGI before the results
- of the first POST are read back.
- To get an acceptable solution takes quite a lot of effort. In general
- you should prefer GET to POST for CGI access from Java. As it says on
- the Javaworld page, the answers to the question are really: you can't,
- don't POST (use GET), use a bean, or cheat.
- Finally, if you request a URL via the URLConnection/HttpURLConnection,
- the server sets the content type, and your applet can use
- URLConnection.getContentType() to get the type. Alternatively, use
- setRequestProperty to set it, like this:
-
-
- url = new URL(cgiUrl);
- urlc = url.openConnection();
- urlc.setRequestProperty(
- "Content-type",
- "application/x-www-form-urlencoded");
-
-
- Other sites:
- There's a pretty good explanation at
- http://www.javaworld.com/javaworld/javatips/jw-javatip41.html
-
- 17. (Sect. 15) How can I write CGI programs in Java?
-
- [*] CGI (the Common Gateway Interface for web servers) is an API for
- writing programs that use the web as its user interface. By far, the
- most popular language for this task is Perl, because of its powerful
- text handling capabilities, and excellent resources available for
- making the jobs of CGI programmers easier. CGI programs can be written
- in any language, including Java.
- Unfortunately, the interface between the web server and the CGI program
- uses environment variables extensively. Use of environment variables
- has always been deprecated in Java, because of portability issues (not
- all systems have environment variables). The way to get around this is
- to write a "wrapper" for the Java program in a language that supports
- environment variables, and can then invoke the Java program with the
- appropriate environment data passed in as Java properties.
- Because the Java runtime environment is not a lightweight process, it
- might take a moment for the CGI program to get started before anything
- happens. This is particularly true on operating systems, like NT, that
- have a large overhead to spawning new processes.
- In preference to using Java for CGI on the server, you might consider
- using the Java servlet API in Netscape's Enterprise Server. This allows
- you to develop server-side programs in Java without suffering the same
- performance restrictions and other limitations of the CGI API.
- Other sites:
- See http://search.netscape.com/comprod/server_central/
- query/eval_guide/enterprise/advantage.html for more details.
-
- 18. (Sect. 15) How can I write the "ping" program in Java?
-
- [*] You can't. Quoting from the Java Networking FAQ,
-
- Ping requires ICMP packets. These packets can only be created
- via a socket of the SOCK_RAW type. Currently, Java only
- allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. It
- seems unlikely that this will be added very soon, since many
- Unix versions only allow SOCK_RAW sockets to be created by
- root, and winsock does not address ICMP packets (win32
- includes an unsupported and undocumented ICMP.DLL).
-
- Other sites:
- You can find the Java Networking FAQ at
- http://www.io.com/~maus/JavaNetworkingFAQ.html
-
- -------------------------------
-
- 16. Security
-
- 1. (Sect. 16) What is a "trusted applet"?
-
- [*] JDK 1.1 introduced the notion of a "trusted applet" which is one
- that has been cryptographically signed to guarantee its origin and make
- it tamper-resistant. Trusted applets can be granted more system access
- privileges than untrusted applets.
- You preconfigure your browser with a list of whose X.509 certificate
- you trust, and then applets arrive with X.509's attesting to their
- keys. It's easier than it sounds.
-
- 2. (Sect. 16) What is the story with Java and viruses? What is the
- blackwidow virus?
-
- [*] Java was designed with security in mind. The security features make
- it very difficult, probably impossible, to attach a virus (self-copying
- code) to a Java applet. There has never been a Java virus carried from
- system to system by applets.
- There has been mention of a "Java virus" called "BlackWidow" in the
- media (it was mentioned in Unigram in late 1996, and obliquely on the
- RISKS newsletter in February 1997). A request to the editor of Unigram
- for more information brought the answer that there was no more
- information, it was just a report of a rumor. As far as is known, this
- story exists only as rumors reported on by the press. There is no
- actual Java virus or blackwidow virus (there was a legitimate
- commercial product of that name, since renamed).
- In spring 1998 there were press reports of a "Java applet" called White
- Ghost. It turns out that it relies on security flaws in ActiveX, and
- the only susceptible systems are Microsoft's Active Desktop. If anyone
- has a URL for a copy of this code, and an analysis of it, please
- contact the FAQ author.
- In August 1998, Symantec had some information about a Java program
- (application) that could append itself to some other Java program. That
- is just normal file processing, no different to a program written in C,
- C++, Fortran, COBOL, etc. What makes PC viruses dangerous is when they
- have a hidden means of travelling between places, such as being
- attached to code that is automatically executed, like boot sector code,
- or Word macro initialization files.
- If anyone has more concrete information about a virus that can attack a
- Java applet (again, this is thought to be impossible), please contact
- the FAQ author.
-
- 3. (Sect. 16) Why do I get the warning string "Unsigned Java Applet
- Window" at the bottom of popup windows in my applets?
-
- [*] This is a security feature, to make certain that users can always
- tell that a window asking for their password and credit card details
- (or whatever) is from an applet. There should be no way for an
- untrusted applet to work around this message.
- Also in the FAQ:
- See also the answer to Q12.7.
-
- 4. (Sect. 16) Where can I find information on signing applets?
-
- [*] Please take a look at the "Code Signing for Java Applets" page at
- http://www.suitable.com/Doc_CodeSigning.shtml. The page explains how to
- sign your Java applet so that it can be used in both
- Navigator/Communicator and Internet Explorer.
-
- 5. (Sect. 16) Where can I find crypto libraries for Java?
-
- [*] Cryptographic libraries are not part of the Java release because US
- Government policy classifies strong cryptography under the same rules
- as munitions. Its export is regulated under the International Traffic
- in Arms Regulations. Many people regard this as a Kafka-esque (and
- futile) attempt to stem the use of cryptography inside the US.
- Other sites:
- o A comprehensive and free crypto library (called Cryptix) is at:
- http://www.systemics.com/software
- o Another crypto library for Java is at:
- http://www.acme.com/java/software/Package-Acme.Crypto.html
- It includes Blowfish, CRC16, CRC32, DES, DES3, IDEA, RC4, ROT13
- (can they really call that "crypto"?), and more.
- o Another pure Java Cryptography toolkit is at
- http://www.freestylesoft.com/products/crypto/avalanche.html (free
- for personal use).
- o One commercial Java encryption source (from Ireland) is:
- http://www.baltimore.ie/jcrypto.htm
- o A complete crypto API for Java (with HTML documentation) at:
- http://www.geocities.com/SiliconValley/Heights/8298
- The library provides comprehensive and complete range of crypto
- library and functions covering DES, 3DES, IDEA, Blowfish ...and
- RSA, DH, DSA and PGP access to Java programmers. The crypto
- functions are based on the C cryptlib, by Peter Gutmann. It would
- be illegal to export this under current US government rules, but
- the author of the code is outside the US, and not subject to US
- export regulations. Download it today before it becomes illegal.
- o Also, data about Sun's Java Cryptography Extension (JCE) is
- available at:
- http://developer.java.sun.com/developer/earlyAccess/jdk12/jce.html
-
- (This may not be exported outside the USA and Canada).
- o An actual port of PGP v2.6.3i to Java is at:
- http://tassun.math.nsc.ru
-
- 6. (Sect. 16) How do I find out what these terms mean?
-
- [*] Read Bruce Schneier's excellent book "Applied Cryptography 2nd Ed."
- for more info on what these terms mean. Read David Kahn's excellent (if
- exhaustive) book "The Codebreakers" for more info on the history and
- background of encryption.
-
- 7. (Sect. 16) Where is Javasoft's Security FAQ?
-
- [*] Javasoft's security FAQ can be found at:
- http://java.sun.com/sfaq/index.html
- Other sites:
- http://java.sun.com/products/jdk/1.1/docs/guide/security/
-
- -------------------------------
-
- 17. For C and C++ Afficionados
-
- 1. (Sect. 17) How do I translate C/C++ into Java or vice-versa?
-
- [*] In general it is not simple to translate C/C++ into Java, as Java
- lacks the arbitrary pointer arithmetic of those languages. If your C
- code does not use pointer arithmetic, automatic translation gets a lot
- simpler. Try these URLs:
- http://www.ist.co.uk (search for X-Designer 4.6: Java edition).
- http://members.aol.com/laffra/c2j.html
- http://www.ilog.com/
-
- Going the other way there are currently three freely-available tools to
- translate Java into C. It seems that these have been done for hacking
- value, rather than practical purposes.
- o j2c from Japan,
- http://www.webcity.co.jp/info/andoh/java/j2c.html
- o Toba from the Sumatra research project, translates 1.0.2 .class
- files into .c source code
- http://www.cs.arizona.edu/sumatra/toba
- o JCC from Nik Shaylor.
- http://www.geocities.com/CapeCanaveral/Hangar/4040/
-
- None of them support the AWT yet, and both j2c and JCC have additional
- restrictions.
-
- There's a product to convert Visual Basic to Java. Details at
- http://www.blackdirt.com and
- http://www.javadelphi.com (also a Delphi-to-Java source converter)
- and
- http://www.tvobjects.com
- There's a product to translate COBOL source to Java source, see
- http://www.Synkronix.com/
-
- This program dumps info about the class file:
- http://www.professionals.com/~cmcmanis/java/dump/index.html
-
- Chuck McManis was one of Sun's original Java implementors.
-
- 2. (Sect. 17) How are finalizers different from C++ destructors?
-
- [*] Java objects are not explicitly deleted and do not have
- destructors. Instead they are implicitly garbage collected when the JVM
- realizes your program can no longer access them. Typically this
- technology is _not_ based on reference counting and _will_ cope with
- circular references.
-
- Every object has a routine called finalize() which will be called
- before the object is collected. This is Java's nearest equivalent to
- C++'s destructor. However, it is not a good idea to rely on
- finalization for the timely freeing of resources.
-
- This is because garbage collection and hence finalization may be
- arbitrarily delayed, and may never happen at all if the program
- terminates before it runs out of memory. You should instead provide
- your objects with methods similar to Graphics.dispose() to free
- resources, and call the dispose() method explicitly when you have
- finished using them - typically within the "finally" clause of a
- "try/catch" block. You may then call your dispose() method from within
- your finalize() method as a last-ditch attempt to free the resource if
- someone forgets.
-
- Alas, all this means the C++ idiom of "object construction is resource
- aquisition" does not translate well to Java. However, note that 90% of
- destructors in C++ are there to free memory, and the GC means you don't
- need to do that in Java. As well as fixing an important source of bugs,
- the GC is essential to Java's security model; without it you could
- forge object references by preserving the reference after the object
- has been deleted.
-
- If your program appears to be crashing due to running out of some
- system resource (like File, Window or Graphics handles), it probably
- because the system is running out of handles before it has run out of
- memory. Check that you have called the dispose() method (or equivalent)
- on every object that uses system resources. You can help the GC a
- little bit more by explicitly NULLing out references that you've
- finished with.
-
- 3. (Sect. 17) What's the Java equivalent of sizeof()?
-
- [*] There isn't one. sizeof() in C and C++ is used in three main
- places:
- 1. To check on the size of a primitive type. In Java, the sizes of
- primitive types are fixed in the language specification (a short
- is _always_ 16 bits; an int is _always_ 32 bits, etc), so this is
- no longer necessary.
- 2. In memory allocation (i.e. malloc (32 * (sizeof(int));) In Java
- you always allocate a specific type of object, rather than a block
- of raw memory that you will fill as you like. The system always
- knows the size of the kind of objects you are allocating. So
- sizeof is not needed.
- 3. In pointer arithmetic (i.e. p += sizeof (int)) Pointer arithmetic
- of this type is not allowed in Java, so this isn't necessary,
- either.
-
- For all these reasons, there is no need for a Java sizeof() operator.
- Some people have suggested that you can find out the size of an object
- by having the object serialize itself to a ByteArrayOutputStream, and
- looking at the bytearray.length.
-
- That won't work because a lot of additional data is written when an
- object is serialized. The additional data includes a description of the
- class, any objects referenced by the serialized object, null references
- (written as a single byte), etc. If you write another instance of the
- same class, the amount of data written can differ dramatically. And if
- you serialize the same object again, it isn't written at all -- even if
- its data fields have changed! Instead, a one byte token and a four byte
- "sequence number" that refer to the first writing are output. Using
- Object Serialization to determine the size of an object does not
- (except by coincidence) give the right answer.
-
- 4. (Sect. 17) Does Java have the equivalent of "const" arguments in C and
- C++?
-
- [*] Java 1.1 adds the ability to use the "final" keyword to make
- arguments constant. When used to qualify a reference type, however,
- this keyword indicates that the reference is constant, not that the
- object or array referred to is constant. For example, the following
- Java code:
-
- void foo(final MyClass c, final int a[]) {
- c.field = 7; // allowed
- a[0] = 7; // allowed
- c = new MyClass(); // final means this is NOT allowed
- a = new int[13]; // final means this is NOT allowed
- }
-
- is roughly equivalent to the following C/C++ code:
-
- void foo(MyClass * const c, int * const a) {
- c->field = 7; // allowed
- a[0] = 7; // allowed
- c = new MyClass(); // const means this is NOT allowed
- a = new int[13]; // const means this is NOT allowed
- }
-
- Java does not have any equivalent to the following C/C++ function
- declarations:
-
- void foo(const MyClass *c); // a pointer to a const class
- void foo(const int *a); // a pointer to a const int
- void foo(const int a[]); // a pointer to an array of const ints
-
- 5. (Sect. 17) Are there any hacks around this?
-
- [*] Certainly! There are always hacks around stuff. One way of
- enforcing constant values is to have two interfaces, a constant one and
- a non-constant one, e.g.
-
- public interface ConstFoo {
- int getValue();
- }
-
- public interface Foo extends ConstFoo {
- int getValue();
- void setValue(int i);
- }
-
- Then when you want to receive a parameter that cannot be modified you
- have:
-
- void noChange(ConstFoo foo);
-
-
- For a parameter that can be modified
-
- void change(Foo foo);
-
-
- 6. (Sect. 17) How can I write C/C++ style assertions in Java?
-
- [*] The two classes shown below provide an assertion facility in Java.
- Set Assert.enabled to true to enable the assertions, and to false to
- disable assertions in production code. The AssertionException is not
- meant to be caught--instead, let it print a trace. Since the exception
- is not meant to be caught, we just extend Error instead of
- RuntimeException. As with RuntimeException, a method does not need to
- declare that it throws Error. In addition programmers are less likely
- to write "catch(Error) ..." than "catch(RuntimeException)".
-
- With a good optimizing compiler there will be no run time overhead for
- many uses of these assertions when Assert.enabled is set to false.
- However, if the condition in the assertion may have side effects, the
- condition code cannot be optimized away. For example, in the assertion
-
- Assert.assert(size() <= maxSize, "Maximum size exceeded");
-
- the call to size() cannot be optimized away unless the compiler can see
- that the call has no side effects. C and C++ use the preprocessor to
- guarantee that assertions will never cause overhead in production code.
- Without a preprocessor, it seems the best we can do in Java is to write
-
- Assert.assert(Assert.enabled && size() <= maxSize, "Too big");
-
- Alternatively, use
-
- if (Assert.enabled)
- Assert.assert( size() <= maxSize, "Too big" );
-
- In this case, when Assert.enabled is false, the method call can always
- be optimized away totally, even if it has side effects. However, an
- opposing view holds that even this might not work in the face of java's
- late binding. If the Assert class is in a package, and if the computer
- the applet/application is running on has a different version with
- Assert.enabled being true, then it's possible that assertions *should*
- be enabled in that case. Therefore, the compiler can't assume that
- enabled is *false* at runtime just because it *is* false in the
- compilation environment. This may be thought perverse, but it could
- happen.
- If a language lawyer wants to weigh in on this theory, please go ahead.
-
- public class AssertionException extends Error {
- public AssertionException(String s) {
- super(s);
- }
- }
-
- public final class Assert {
- public static final boolean enabled = true;
- public static final void assert(boolean b, String s) {
- if (enabled && !b)
- throw new AssertionException(s);
- }
- }
-
- 7. (Sect. 17) How do I do stuff like scanf and sscanf in C/C++? And how do
- I do stuff like sprintf, e.g.
-
- float x = 12345.6789;
- printf("%6.3f/n", x);
-
- [*] You can break a string like "5 loaves 2 fishes" into its parts by
- using java.util.StringTokenizer. This is the Java equivalent of
- sscanf().
-
- StreamTokenizer does a similar thing on a file or any stream (i.e, what
- scanf() and fscanf() do in C).
-
- To do formatted character output, create a format string, and then use
- that to format your binary value, e.g.
-
- import java.text.*;
-
- float fi = 1234.56789F;
- DecimalFormat mydf = new DecimalFormat( "###0.000" );
- mydf.setMinimumIntegerDigits(3); // for example
- System.out.println( mydf.format(fi) );
-
- gives:
- 1234.567
-
- If you want to see a float print out as "0.0000001" instead of "1E-7",
- use:
-
- java.text.DecimalFormat myFmt = new
- java.text.DecimalFormat("#,###,###,###.############");
- System.out.println(myFmt.format(myFloat));
-
- There are lots of different characters you can feed to the
- DecimalFormat constructor, not just "0" and "#". See
- $JAVAHOME/src/java/text/DecimalFormat.java source for details.
-
- 8. (Sect. 17) What is the Java equivalent of C++'s "friend"?
-
- [*] The keyword "friend" in C++ is a hack to allow a piece of code to
- access the private member declarations of another class. In Java, you
- would do this by labelling, not the friend, but the private members.
- Instead of making them private, make them either protected or package
- (no keyword) or public.
-
- The four different Java protection levels are: private, package,
- protected, and public.
- o private members can only be accessed by the containing class and
- internal classes.
- o package (specified by omitting other keywords) is the default
- level of protection; members are accessible from any class within
- the package of the containing class.
- o protected is package-level-access plus access to sub-classes of
- the containing class. So "protected" is less protected than the
- default.
- o public fields in public classes are accessible from all classes.
-
- 9. (Sect. 17) Does anything like the C++ Standard Template Library exist
- for Java?
-
- [*] Yes, only it's better and simpler to use in Java. It's called the
- Java Generic Library. This library (JGL) is freely downloadable from
- http://www.objectspace.com/
-
- It includes about a dozen nice data structures (including sets and
- bags) and algorithms like unions, searching, and sorting.
-
- It has over 100,000 users and 11 OEM distributors. [Some Java vendors
- are bundling it with their next release]
-
- 10. (Sect. 17) What happens to post-increment when an exception is thrown?
-
- [*] If you have the code:
-
- array[i++] = foo();
-
- and foo() throws an exception, i will be incremented anyway. This can
- cause problems if sometimes foo() throws an exception and you don't
- want i incremented in cases when it does.
-
- This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand
- of a binary operator appears to be fully evaluated before any part of
- the right-hand operand is evaluated." (assignment is taken as a binary
- operator). Note that this is not how C++ behaves.
-
- -------------------------------
-
- 18. Java Idioms
-
- See also the list of Java Design Patterns at
- http://http://c2.com/cgi/wiki?JavaIdioms
-
- 1. (Sect. 18) What are the naming conventions in Java?
-
- [*] The naming conventions are straightforward:
- o Package names are guaranteed uniqueness by using the Internet
- domain name in reverse order: com.javasoft.jag - the "com" or
- "edu" (etc.) part used to be in upper case, but now lower case is
- the recommendation.
- o Class and interface names are descriptive nouns, with the first
- letter of each word capitalized: PolarCoords. Interfaces are often
- called "something-able", e.g. "Observable", "Runnable",
- "Sortable".
- o Object and data (field) names are nouns/noun phrases, with the
- first letter lowercase, and the first letter of subsequent words
- capitalized: currentLimit.
- o Method names are verbs/verb phrases, with the first letter
- lowercase, and the first letter of subsequent words capitalized:
- calculateCurrentLimit.
- o Constant (final) names are in caps: UPPER_LIMIT.
- Other sites:
- o Check out the section "Naming Conventions" in the language
- specification:
- http://java.sun.com/docs/books/jls/html/6.doc.html#11186
- o Also take a look at Doug Lea's draft coding standard:
- http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
-
- 2. (Sect. 18) How do I convert a String to an int?
-
- [*] There are several ways. The most straightforward is:
-
- String mystring = numString.trim();
- int i = Integer.parseInt(myString);
- long l = Long.parseLong(myString)
-
-
- or
-
- String mystring = numString.trim();
- i = Integer.parseInt(myString,myIntRadix);
-
-
- Note 1: There is a gotcha with parseInt - it will throw a
- NumberFormatException for String values in the range "80000000" to
- "ffffffff". You might expect it to interpret them as negative, but it
- does not. The values have to be "-80000000" .. "-ffffffff" to be
- properly recognized as negative values. This is true for all radixes.
- According to Bug Parade bug report 4068580, the proper way to generate
- negative-valued hex Strings for eventual use by parseInt() is with
- Integer.toString(i, 16). Once that high "sign bit" is on, without the
- accompanying character, parseInt() says "too big".
- Note 2: There are similar methods for Byte, Short, and Long. Use
- myString.trim() to get rid of unwanted spaces before the conversion.
- Some of the parse methods can cope with spaces, others can't. They were
- written by two different people.
-
- int i = Integer.valueOf(my_str).intValue();
-
-
- also works but involves the creation of an extra object. Note: the
- pre-FCS JDK 1.2 documentation at one point said that parseDouble and
- parseFloat methods were to be introduced, but this does not seem to be
- the case (see bug 4160672). JDK 1.2.
-
- float f = Float.valueOf(my_str).floatValue();
- double d = Double.valueOf(my_str).doubleValue();
-
-
- 3. (Sect. 18) How do I convert an int to a string?
-
- [*] Try any of these:
-
- String s = String.valueOf(i);
-
-
- or
-
- String s = Integer.toString(i);
-
-
- or
-
- String s = Integer.toString(i, radix);
-
-
- or
-
- // briefer but may result in extra object allocation.
- String s = "" + i;
-
-
- Note: There are similar classes for Double, Float, Long, etc.
-
- 4. (Sect. 18) How do I print the hex value of an int?
-
- [*] You can print the hex equivalent of an int with:
-
- int i = 0xf1;
- System.out.println("i is hex " + Integer.toHexString(i) );
-
-
- OK, how do I read a hex string into an int?
-
- int i = Integer.valueOf(myHexString, 16).intValue();
-
-
- 5. (Sect. 18) How can you send a function pointer as an argument?
-
- [*] Simple answer: use a "callback". Make the parameter an interface
- and pass an argument instance that implements that interface.
-
- public interface CallShow { public void Show( ); }
-
- public class ShowOff implements CallShow {
- public void Show( ) { .... }
-
- public class ShowOff2 implements CallShow {
- public void Show( ) { .... }
-
- public class UseShow {
- CallShow savecallthis;
-
- UseShow( CallShow withthis ) {
- savecallthis = withthis;
- }
-
- void ReadyToShow( ) { savecallthis.Show( ); }
- }
-
- // in some other class that uses all this stuff:
- UseShow use_1 = new UseShow( new ShowOff() );
- UseShow use_2 = new UseShow( new Showoff2() );
-
-
- and then the ReadyToShow() method on use_1 or use_2 will call the
- appropriate method, as if you had stored a pointer to the method.
-
- 6. (Sect. 18) How do I execute a command from Java?
-
- [*] Use
-
- Runtime.getRuntime().exec( myCommandString )
-
-
- where myCommandString is something like "/full/pathname/command". An
- applet will need to be signed in order to allow this.
-
- Note, there are known bugs associated with reading output from
- commands.
-
- 7. (Sect. 18) How do I do I/O redirection in Java using exec()?
-
- [*] This solution works on Unix platforms using either JDK 1.0.2, or
- JDK 1.1. The trick is to use an array of Strings for the command line:
-
- String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
-
-
- If you don't do this, and simply use a single string, the shell will
- see the -c and /bin/ls and ignore everything else after that. It only
- expects a single argument after the -c.
-
- import java.io.*;
- import java.util.*;
-
- class IoRedirect {
- public static void main(String Argv[]) {
- try {
- String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
- Process p = Runtime.getRuntime().exec(command);
- p.waitFor();
- System.out.println("return code: "+ p.exitValue());
- } catch (IOException e) {
- System.err.println("IO error: " + e);
- } catch (InterruptedException e1) {
- System.err.println("Exception: " + e1.getMessage());
- }
- }
- }
-
-
- 8. (Sect. 18) So why can't I exec common DOS commands this way (as in
- 17.7)?
-
- [*] The reason is that many of the DOS commands are not individual
- programs, but merely "functions" of command.com. There is no DIR.EXE or
- COPY.EXE for example. Instead, one executes the command processor
- (shell) explicitly with a request to perform the built-in command, like
- so:
- Runtime.getRuntime().exec("command.com /c dir") for example. On NT, the
- command interpreter is "cmd.exe", so the statement would be
- Runtime.getRuntime().exec("cmd /c dir")
- This occurs on any OS where some commands are actually interpreted
- directly by the shell.
-
- 9. (Sect. 18) OK, how do I read the output of a command?
-
- [*] As above (17.6, 17.7), adjusted like this:
-
- BufferedReader pOut= new BufferedReader(
- new InputStreamReader(p.getInputStream()));
- try {
- String s = pOut.readLine();
- while (s != null) {
- System.out.println(s);
- s = pOut.readLine();
- }
- } catch (IOException e) { }
-
-
- Another possibility is to read chunks of whatever length as they come
- in:
-
- ...
-
- p = r.exec(cmd);
- InputStream is = p.getInputStream();
- int len;
- byte buf[] = new byte[1000];
- try {
- while( (len = is.read(buf)) != -1 ) {
- String str = new String(buf,0,0,len);
- System.out.println( "Process out: " + str );
- }
- } catch( java.io.EOFException eof ) { ...
- } catch( java.io.IOException ioe ) { ... }
-
-
- 10. (Sect. 18) How do I compile code which has a cyclic dependency, i.e
- class pkg1.X contains a reference to class pkg2.Y ?
-
- [*] You throw both classes at the compiler at the same time.
- javac pkg1/X.java pkg2/Y.java
-
- 11. (Sect. 18) How can I store the errors from the javac compiler in a DOS
- file? javac foo.java > errorfile doesn't work.
-
- [*] javac writes errors to stderr, so on NT use:
- javac myfile.java 2> errors.dat
- On Win95, this doesn't work (as command.com is very poor software), so
- you have to use the javac error redirection mechanism:
- javac -J-Djavac.pipe.output=true myfile.java > errors.txt You typically
- use this when a compilation produces a lot of error messages, and they
- scroll off the DOS window before you can read them. Alternatively, you
- can get a scollbar to appear on a DOS window by changing the properties
- with the "Layout" tab. Change the Screen Buffer Size Height: to some
- multiple > 1 of the Window Size Height. E.g. use a buffer height of 100
- and screen height of 25 (the default). This will give you three buffers
- of scroll "history."
-
- 12. (Sect. 18) How can I pretty-print Java source?
-
- [*] Try:
- o http://www.CS.ORST.EDU/~speton/percolator/ (currently in beta)
- o http://www.geocities.com/~starkville
- o http://www.parallax.co.uk/~rolf/download/jpp.pl
- Some Unix utilities work adequately:
- o indent (fails with "//" comments though)
- o cb (very few style choices though)
- o alias printjava 'vgrind -lC++ -t -w \!* | lp' works pretty well
- too.
- Perhaps the best tools are the GNU utilities. Use enscript to generate
- postscript files with Java-specific formatting. Then use
- GhostScript/GhostView to preview and print the files to a
- non-PostScript printer, if necessary. The scripts can be found at:
- o GNU Enscript - pretty printer and PostScript formatter
- o Ghostscript, Ghostview, and GSView for Unix
- o gsv25w32.zip - GSView for NT (requires the following Ghostscript
- files)
- o gs510ini.zip - Ghostscript configuration, initialization, and
- example files
- o gs510w32.zip - Ghostscript core binaries for Windows NT
- o gs510fn1.zip - Ghostscript standard fonts
-
- 13. (Sect. 18) What is the point of creating the temporary reference to
- this.layoutMgr?
-
- [*] This code is from the 1.0 AWT, and the programmer was probably
- pretty skilled.
-
- public synchronized void layout() {
- LayoutManager layoutMgr = this.layoutMgr;
- if (layoutMgr != null) {
- layoutMgr.layoutContainer(this);
- }
- }
-
-
- The code makes a local copy of a global variable for one or both of two
- reasons.
- The first reason is that accessing local variables can be faster than
- accessing (non final) member variables It's good for loops or where
- there are many references in the source.
- The second reason is so that even if other threads update the global,
-
- this.layoutMgr = someOtherLayoutMgr;
-
- This method will still have a pointer to the original layoutMgr.
- If the local variable were omitted, and another thread used the
- setLayout() method to change layoutMgr to null between when the layout
- method checked for null and when it invoked layoutMgr's layoutContainer
- method, a NullPointerException would result.
- Note that the synchronized keyword on the layout method doesn't help
- any, since setLayout (which could make such a dire change) isn't
- synchronized. Synchronized methods only lock out other synchronized
- methods on this object. (The unhelpful synchronized keyword on the
- layout method is gone in JDK 1.1.)
- There are two alternative solutions. One would be to make setLayout
- synchronized and make layoutMgr private, so that it can't be set other
- ways. This provides a stronger form of thread serialization, in that
- you would never be able to see an old layout manager being used after
- it had been replaced. However, it is slower. Another option that
- provides no increase in thread serialization over the original would be
- to catch the NullPointerException.
- Threaded programming is hard! This idiom was probably put in place by
- someone who got really bitten by this in the past.
-
- 14. (Sect. 18) What is the difference between "a & b" and "a && b" ?
-
- [*] "a & b" takes two boolean operands, or two integer operands. It
- always evaluates both operands. For booleans, it ANDs both operands
- together producing a boolean result. For integer types, it bitwise ANDs
- both operands together, producing a result that is the promoted type of
- the operands (i.e. long, or int). "|" is the corresponding bitwise OR
- operation. "^" is the corresponding bitwise XOR operation.
-
- "a && b" is a "conditional AND" which only takes boolean operands. It
- always avoids evaluating its second operand if possible. If a is
- evaluated to false, the AND result must be "false" and the b operand is
- not evaluated. This is sometimes called "short-circuited" evaluation.
- "||" is the corresponding short-circuited OR operation.
-
- Possible mnemonic: The longer operators "&&" or "||" try to shorten
- themselves by not evaluating the second operator if they can.
-
- 15. (Sect. 18) If I create a thread, and then null out the reference to it,
- what happens to the thread? Does it get interrupted or what?
-
- [*] The code looks like this:
-
- Thread t = new Thread( my_runnable_obj );
- t.start();
- ...
- t = null; // what happens to the thread?
-
-
- The answer is that you may no longer have a reference to the thread,
- but the JVM still does. Once a thread is started, and as long as it
- keeps running, it is a root object. Root objects are the starting
- points for "things in use" that the garbage collector uses.
-
- 16. (Sect. 18) How do I calculate the number of days between two dates?
-
- [*] There is no API for this (there should be), but you can calculate
- it by hand like this:
-
- Calendar earlierDate = new GregorianCalendar();
- Calendar laterDate = new GregorianCalendar();
-
- earlierDate.set(1997, 1, 1, 0, 0, 0); // Jan 01, 1997
- laterDate.set(1998, 1, 1, 0, 0, 0); // Jan 01, 1998
-
- // the first getTime() returns a Date, the second takes
- // that Date object and returns millesecs since 1/1/70.
- // The API has misleading and horrible naming here, sorry.
- long duration = laterDate.getTime().getTime() -
- earlierDate.getTime().getTime();
-
- long nDays = duration / (24 * 60 * 60 * 1000);
- System.out.println("difference in days: " + nDays);
-
-
- Or, use int julian = myCalendar.get(Calendar.DAY_OF_YEAR); and
- subtract, making sure to subtract the years too. Alternatively, use
- BigDate at http://mindprod.com.
-
- For the ultimate in generality, get ACM's Collected Algorithm 199,
- recode it in Java (takes about 30 minutes), compute the Julian date for
- each end point, and subtract the two numbers. If you do this, please
- donate the code to public domain, and send it to me. The ACM algorithms
- aren't online (they should be). Look for this one in Communications of
- the ACM, page 444, vol 6, issue 8, Aug 1963. There's a follow up in
- CACM, p661, vol 7, issue 11, Nov 1964 by D.K. Oppenheim. The algorithm
- is in Algol 60 for all you amateur historians.
-
- 17. (Sect. 18) How can a Java program determine the level of JDK support
- given by the underlying VM? I.e. is it running in a JDK 1.0.2 or 1.1
- VM?
-
- [*] Look at the java.version system property with:
-
- String ver = System.getProperty("java.version");
-
-
- There isn't a lot of standardization on the string contents however.
- Another possibility is to try { ... } to load a class that is unique to
- one release, like this:
-
- boolean isJDK1_1 = true;
- try {
- // java.awt.Cursor is available only in the 1.1.x JDK
- Class cls = Class.forName("java.awt.Cursor");
- } catch (Exception e) {
- // we should have written 'ClassNotFoundException e',
- // but Communicator generates security exception instead.
- isJDK1_1 = false;
- }
-
- This approach has the advantage that it can be compiled by any version
- compiler.
-
- 18. (Sect. 18) How can I set a system property?
-
- [*] JDK 1.2 has
-
- System.setProperty( "property", "new value" );
-
-
- Until then, you can get all the properties, and set just the one you
- want with code like this:
-
- System.getProperties().put("property", "new value" );
-
-
- 19. (Sect. 18) How can I clone using serialization?
-
- [*] Look at the code below, submitted by expert programmer John Dumas.
- It uses serialization to write an object into a byte array, and reads
- it back to reconstitute a fresh copy. This is a clever hack!
-
- import java.io.ByteArrayOutputStream;
- import java.io.ByteArrayInputStream;
- import java.io.ObjectOutputStream;
- import java.io.ObjectInputStream;
-
- public class Cloner {
- private Cloner() {}
-
- public static Object cloneObject(Object o) throws Exception {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(bOut);
-
- out.writeObject(o);
-
- ByteArrayInputStream bIn =
- new ByteArrayInputStream(bOut.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bIn);
-
- return(in.readObject());
- }
-
- public static void main(String args[]) throws Exception {
- java.util.Vector v = new java.util.Vector();
- v.addElement(new StringBuffer("Hello"));
-
- java.util.Vector vClone =
- (java.util.Vector)Cloner.cloneObject(v);
-
- // Changing the StringBuffer int the cloned vector has no
- // effect on the original StringBuffer object --
- // demonstrating that we have indeed done a deep copy
-
- ((StringBuffer)vClone.elementAt(0)).append(" world");
-
- StringBuffer sb = (StringBuffer)v.elementAt(0);
- System.out.println(sb.toString());
-
- sb = (StringBuffer)vClone.elementAt(0);
- System.out.println(sb.toString());
-
- int array[] = { 1, 2, 3, 4, 5 };
-
- int arrayClone[] = (int [])Cloner.cloneObject(array);
-
- // Again, changes to an element in the cloned array do not
- // have any effect on the original
-
- arrayClone[0]++;
-
- System.out.println(array[0]);
- System.out.println(arrayClone[0]);
- }
- }
-
- The main() routine is just a driver. All the cleverness is in the very
- brief cloneObject(). It does a "deep" clone, which is what you usually
- want (though Java gives you a "shallow" clone by default).
-
- -------------------------------
-
- 19. Java GOTCHA'S
-
- 1. (Sect. 19) What is a "GOTCHA" (for non-English native speakers)?
-
- [*] It is an abbreviation of "Got you!" It is the triumphant
- exclamation that a bug or programming idiom makes as it traps the
- unwary programmer. This section details some of the popular "gotcha's"
- of Java.
-
- See also the list of Java Gotcha's at
- http://mindprod.com/gloss.html
-
- 2. (Sect. 19) Why can't I filter filenames with the accept() method?
-
- [*] It's a known bug. FileDialog doesn't call FilenameFilter.accept().
- The bug id is 4031440, and it can be seen at the Java Developer
- Connection.
-
- There is no way to implement FilenameFilter support with the current
- reliance on the Win32 common file dialog. To support FilenameFilter,
- the FileDialog needs to issue a callback for each file it wants to
- display, which the FilenameFilter can veto. But the Win32 common
- FileDialog doesn't have any way to issue callbacks. Instead it accepts
- simple wildcard patterns for choosing files which match a certain
- pattern. That's a reasonable alternative to FilenameFilters, but that
- model isn't supported by the current Java API.
-
- FileDialog will need to be rewritten to support FilenameFiltering, and
- JDK 1.2 is the earliest feasible point for changing the API.
-
- JFC has a JFileChooser class that is probably a better bet for you to
- use for file dialogs.
-
- 3. (Sect. 19) I changed a final value, and recompiled just the file that
- it was in, and the entire rest of the program used the old value!
-
- [*] This is the "expected" behavior. If you have this in one file
-
- class Flags { final static boolean debug = true; }
-
- and you change it to, and recompile just this file:
-
- class Flags { final static boolean debug = false; }
-
- Then the rest of your Java .class files will still see it as "true".
-
- When you declare a "static final int" (or any other primitive), the
- compiler turns that into a compile time constant whose value can be
- substituted wherever it is used in your program. If you update the
- value in the source file, you'll need to recompile every class that
- uses it.
-
- See Java Language Specification, section 13.4.8 "final Fields and
- Constants": "We call a field that is static, final, and initialized
- with a compile-time constant expression a primitive constant. If a
- field is a primitive constant, then deleting the keyword final or
- changing its value will not break compatibility with pre-existing
- binaries by causing them not to run, but they will not see any new
- value for the constant unless they are recompiled."
-
- 4. (Sect. 19) What is the "substring trap"?
-
- [*] The "substring trap" is the name for a mistake that is all too easy
- to make when using the substring() method of class String. The method
- signature is:
-
- public String substring(int beginIndex, int endIndex)
-
- The name "endIndex" suggests that is the index where the Substring
- ends.
-
- But in fact, the substring extends only to the character at position
- (endIndex-1)! It seems to be done this way so that
- s.substring(0,s.length()) is equal to s. If so, the name of the second
- parameter should be something like endInxLessOne or Length. But not the
- confusing and misleading endIndex. Beware of the substring trap.
-
- 5. (Sect. 19) Why does getGraphics() return null on my offscreen image?
-
- [*] The following code
-
- class MyFrame extends Frame {
- MyFrame() {
- Image offscreen = createImage(100,100);
- Graphics offg = offscreen.getGraphics();
- }
- ...
- }
-
- will usually not work, since the peer will not exist at this time.
- Without the peer for the Frame, you cannot succeed in creating
- offscreen Images. (There's no problem creating Produced Images without
- a peer. Trying to draw them, of course, is another matter).
-
- One "standard" form of offscreen code looks like this: (note the reuse
- of the Graphics and Image objects for as long as possible)
-
- class Gumble extends java.awt.Something {
- private Image offi;
- private Graphics offg;
-
- public void update(Graphics g) {
- if (g == null) return; // Paranoia
- Dimension size = size();
- if ( offi == null
- || offi.getWidth()!=size.width
- || offi.getHeight()!=size.height ) {
- if (offg!=null) offg.dispose();
- offi = createImage(size.width, size.height);
- offg = offi.getGraphics();
- // Regenerate offi here...
- }
- // If you use getClipBounds() here,
- // check that for being null, too!
- // several implementations have been known to pass them....
- g.drawImage(offi);
- }
-
- public void paint(Graphics g) {
- update(g);
- }
- }
-
- See also Question 8.7
-
- 6. (Sect. 19) The dynamic type of a method argument doesn't seem to be
- used to choose an overridden method at runtime.
-
- [*] Correct. Generally, if you invoke a method on an object, the
- object's actual runtime type, not the type of the reference that you
- used to reference it, determines which method is invoked. This is
- regular polymorphism.
-
- It's not the same for object parameters: the compiler decides at
- compile time, depending on the types of the parameter expressions,
- which method signature to use, and this is "hardwired" into the
- bytecode. The compiler does not look at the object argument at runtime
- and say "ah, this is a derived type, so I will choose the method that
- takes the derived type as an argument."
-
- This is best seen in a code example:
-
- class Base { }
- class Derived extends Base { }
-
- public class foo {
-
- public static void method(Base b) {
- System.out.println("In the base method...");
- }
-
- public static void method(Derived d) {
- System.out.println("In the derived method...");
- }
-
- public static void test(Base b) {
- if (b instanceof Derived)
- System.out.print("Derived: ");
- else
- System.out.print("Base: ");
-
- method(b); // which method? method(base) or method(derived)?
- }
-
- public static void main(String args[]) {
- Base b = new Base();
- Derived d = new Derived();
-
- System.out.println("test calls.");
- test(b);
- test(d);
- }
- }
-
- Running the program gives an output of
-
- test calls.
- Base: In the base method...
- Derived: In the base method...
-
- See JLS section 15.11.4.4 and 15.11.3:
- "If class S contains a declaration for a method named m with the same
- descriptor (same number of parameters, the same parameter types, and
- the same return type) required by the method invocation as determined
- at compile time then this is the method to be invoked."
-
- 7. (Sect. 19) Why did I lose my updates when I changed data fields in a
- graph that I was serializing?
-
- [*] Quoting from the object serialization specification at:
- http://www.javasoft.com/products/jdk/1.1/docs/
- guide/serialization/spec/serial-arch.doc.html#4176
- The writeObject method serializes the specified object and
- traverses its references to other objects in the object graph
- recursively to create a complete serialized representation of the
- graph.
-
- Within a stream, the first reference to any object results in the
- object being serialized or externalized and the assignment of a
- handle for that object. Subsequent references to that object are
- encoded as the handle.
-
- In other words, changing an object and then writing it again does not
- really write it twice. Instead it just writes a reference back to the
- first occurrence, losing any fields that have changed in the meantime.
-
- There are three ways around this: (1) (inefficient) Reset (or close and
- reopen) the stream, and start again by writing the new value of the
- object. This is drastic -- you are throwing away all the serialization
- that you have already done.
- (2) (kludgey) Create a new object and write that.
- (3) (could be a lot of work) Write your own protocol for object
- serialization. Have something like a data stream where the contents of
- an object are marked by special identifiers. Each "end" of the stream
- can decide whether it will use a new object each time or reuse an
- existing object.
-
- 8. (Sect. 19) When I click on a Java window frame, it doesn't close!
-
- [*] You need to add the code to listen for a window closing event, and
- take the appropriate action (hide the window, exit the program if the
- top level frame, etc).
-
- The window closing event handler is simple:
-
- Frame mf = new Frame("binky");
- mf.addWindowListener( new WindowAdapter() {
- public void windowClosing(WindowEvent we) {
- System.exit(0); // or setVisible(false); etc.
- } });
-
- This really should be the default behavior of an AWT Frame. So you'll
- be delighted to hear that JavaSoft has "made it so" for the JFrame
- Swing component. That leads to a slightly different problem. See
- Question 4.3.3. See also Question 13.9.
-
- 9. (Sect. 19) What's the deal with "super"? How far back into parent
- classes can I go?
-
- [*] The most common use of super is the call "super()" to invoke a
- constructor in the superclass. The keyword "super" is also used to
- access fields of any superclass (not just the immediate superclass)
- that are hidden by an identically named feature in the current class.
-
- However there is no way to "chain" several super's together, and reach
- back higher into the parent class hierarchy. E.g. do not think that
- "super.x" means the "x of parent" and "super.super.x" means the "x of
- grandparent". This is a very common mistake. There is no
- "super.super.x". Looking at the generated byte code, if you have
-
- class Parent { }
-
- class Child extends Parent { }
-
- then, in Child "super.someParentMethod();" means "invokespecial
- X.someParentMethod()" in the JVM, not "invokevirtual".
- Invokespecial means "call the exact method I am telling you."
- Invokevirtual means "call the right method for whatever object this
- is".
-
- 10. (Sect. 19) When I change some component (e.g. a new label on a button)
- I don't see the change on the screen immediately even if I repaint().
-
- [*] You need to add these calls, instead of the repaint():
-
- invalidate();
- validate();
-
- They cause the component hierarchy to be marked as needing to be laid
- out again, and the validate causes that to be done. It may be
- expensive, but is always the most reliable way of getting the peers to
- recalculate size and to do what is needed to bring the display up to
- date.
-
- 11. (Sect. 19) Why aren't popup menus working cross-platform for me?
-
- [*] On Windows, the pop-up trigger is a mouse release (except in
- certain programs like Netscape Communicator). On Unix, the pop-up
- trigger is a mouse press.
-
- Therefore you need to ask the question isPopupTrigger() in both the
- mousePressed() and mouseReleased() methods when implementing the
- MouseListener interface. Alternatively override Component's
- processMouseEvent as a central place for handling mouse input.
-
- 12. (Sect. 19) Why aren't newlines working cross-platform for me?
-
- [*] Code like this:
-
- if (c == '\n')
- fin = true;
-
- is not cross-platform. On Unix the line terminator is "\n", on Windows,
- it is frequently "\r\n", on the Mac it is "\r".
-
- The call System.getProperty("line.separator") will return a string
- containing the platform-specific line separator character(s), and you
- then need to compare it according to how your data is formatted (e.g.
- compare 2 characters or one). There is also a property for the
- separator character in file pathnames, and other values too.
-
- 13. (Sect. 19) Why didn't my text display in my GUI? Is the Inset wrong?
-
- [*] The most common Inset problem is not an Inset problem at all, but
- rather that people just assume the x,y location of a
- Graphics.drawString() actually refers to the top left part of the
- string image. In fact it refers to the baseline. So you'll need to take
- the font metrics into account:
-
- g.drawString("Hello World",0,getFontMetrics(getFont()).getAscent());
-
- 14. (Sect. 19) Why did my polygon come out the wrong shape?
-
- [*] This question and answer comes directly off
- comp.lang.java.programmer, and deserves to be immortalized for
- posterity.
- When I use fillPolygon with the following points I get two inverted
- triangles instead of a rectangle. Why?
-
- int xPoints[] = {71, 78, 71, 78};
- int yPoints[] = {147, 147, 130, 130};
- g.fillPolygon(xPoints, ypoints, xPoints.length);
-
- Developer Felix Pahl supplied the answer in limerick form:
- o A developer (for details bored her)
- didn't follow the polygon's border
- so instead of right angles
- she got two triangles
- 'cause the endpoints were in the wrong order!
-
- You must put the points in the order you would encounter them in if you
- went round the polygon's border. The filling algorithm is doing the
- right thing! Try drawing the points on paper to see:
-
- 71,130 78,130
- O--------O
- | |
- | |
- | |
- o--------o
- 71,147 78,147
-
- Under JDK1.1, the two endpoints are connected automatically and you
- would order the array elements as:
-
- int xPoints[] = { 71, 78, 78, 71};
- int yPoints[] = {130, 130, 147, 147};
-
- Under JDK1.0.2, you have to explicitly connect the two endpoints, and
- you would write the array elements as:
-
- int xPoints[] = { 71, 78, 78, 71, 71};
- int yPoints[] = {130, 130, 147, 147, 130};
-
- 15. (Sect. 19) Why can't I see all the components I added to a Frame?
-
- [*] If you have code like:
-
- Frame myframe = new Frame("Child Frame");
- myframe.resize(512,384);
- myframe.add(new Label("Child"));
- myframe.show();
-
- you may find that the Label does not show up in the Frame. Or it may
- show up in appletviewer, but not in a browser.
-
- The default layout manager for Frame is BorderLayout. Components
- positioned with a BorderLayout must include a positioning constant to
- be correct. So, change the add to
-
- myframe.add("Center", new Label("Child"));
-
- and all will be well.
-
- 16. (Sect. 19) Why do I get the wrong results when I compare two Strings
- together?
-
- if (s1 == s2)
-
- is giving me funny results.
-
- [*] The comparison using "==" on objects, like Strings, is asking the
- question "do these two objects have the same reference?". That is, do
- they have the same address, and hence are not two object but one? What
- you most probably meant is "do these two Strings have the same
- contents?" which you can express this way:
-
- if ( s1.equals(s2) )
-
- This is a very, very easy mistake to make and impossible to spot until
- you have had it explained to you.
-
- People talk about "interning" a String. That means calling the intern()
- method on a String. This places the String in the runtime constant pool
- if it was not already there. The compiler is required to intern() all
- literal Strings. If you intern() all your Strings as well then all
- duplicates are shared and comparisons can be done by the (much faster)
- address comparison rather than content comparison. It's a performance
- optimization. See also Q3.22.
-
- Note that this comparison error also occurs with other objects, not
- just Strings. The code:
-
- if (getBackground() == Color.black)
-
-
- is a test for object identity, rather than content identity. It will
- work if you originally setBackground(Color.black). To avoid difficult
- debugging in the future, you almost certainly want to say
-
- if (getBackground().equals( Color.black ) )
-
-
- or even (in this visual case) compare the darkness of the RGB values of
- the pixels.
-
- 17. (Sect. 19) Why doesn't final prevent my object from changing?
-
- [*] You have code like this
-
- final StringBuffer s = new StringBuffer("don't change me");
- // ...
- s.append(", but I did");
- System.out.println(s);
-
- And the new value of s is "don't change me, but I did". The reason is
- that the "final" modifier makes the reference variable (here, s) final,
- not the object that s points to. It means that the reference variable
- cannot be changed to point to some other StringBuffer. The state of the
- StringBuffer can still be modified by calling methods on it or directly
- assigning to its public fields.
-
- The right way to think about final is that it prevents you assigning to
- that particular variable. The only way to make the fields of an object
- constant (unchanging) is to make all its data fields private, and not
- provide any set methods for them, only get methods. Even that won't
- stop other objects of the same class adjusting it.
-
- 18. (Sect. 19) Why can't the compiler find my package?
-
- [*] When trying to compile a file in a package you get a compiler error
- like:
-
- DBTest.java:10: Class database.Table not found in type declaration.
-
- The file Table.java and DBTest.java are in the same directory. They
- both have "package database;" at the top of the file. The current
- directory is included in the classpath.
-
- The reason is that when compiling packages, you have to be at the 'top'
- of the directory/package hierarchy. So to compile both Table.java and
- DBTest.java, you have to be in the directory that contains the database
- directory (i.e. where the package hierarchy starts), and just:
-
- javac database/Table.java
- javac database/DBTest.java
-
-
- and it should all compile fine.
-
- 19. (Sect. 19) I have a program with keyboard input and a button. When the
- user hits the space bar, the button gets pressed as it is in focus!
-
- [*] The VM sets the focus on the first traversible object in the UI. If
- you want the button not to be assigned focus by default, you must
- subclass the button and override the isFocusTraversable() method to
- return false.
-
- Another approach is to manually set the focus on some other component
- (say the Frame) when you show the window. To do so you have to jump
- through hoops to outsmart the VM that is trying to set it on the
- button. One approach is to listen for the windowActivated event and set
- a Swing Timer to do a requestFocus() on the frame about 0.1 seconds
- after the activated message. This seems convoluted, but it is the only
- thing found that consistently works cross platform.
-
- Another reader suggests that if the frame normally gets the focus
- first, you can override its gotFocus() event and set the focus to the
- component you want. Don't forget to return true!
-
- 20. (Sect. 19) What's the hidden size limitation of String serialization?
-
- [*] If you wish to Serialize a string, be alert to the restriction
- that:
- The size of the String, when UTF-encoded, must be < 64Kb
- So for robust code you have to examine the String once to ensure that
- it will be less than 64Kb after encoding, and then have the JVM
- effectively repeat that work in the process of encoding, when you write
- it to an ObjectOutputStream.
-
- A possible workaround that is to strip the string down to "byte[]" and
- pass it around in RMI that way. The code with this restriction is in
- DataOutputStream
-
- public final void writeUTF(String str)
- ...
- [perform the size-after-conversion-to-UTF computation]
- ...
- if (utflen > 65535)
- throw new UTFDataFormatException();
- ...
-
- RMI relies on serialization, so RMI has the same String size
- limitation.
- 21. (Sect. 19) When I change a field in just one object in my array, that
- field changes in all the objects in my array!
-
- [*] Here the problem is probably that you have initialized the array
- with N references to the same one object.
-
- This is easy to overlook, because arrays in Java only contain
- references to objects, not objects. (Or they can contain primitives).
- LI>(Sect. 19) Do DrawRect and FillRect work on rectangles of the same
- size?
-
- [*] No. java.awt.Graphics.drawRect draws a rectangle that's 1 pixel
- wider and 1 pixel taller than a rectangle drawn by fillRect.
-
- -------------------------------
-
- 20. Further Resources
-
- 1. (Sect. 20) Are there any commercial/shareware/free Java libraries?
-
- [*] Take a look at the Java Collection Framework, a group of classes
- that are part of Java 1.2. These classes implement general-purpose data
- structures, and they will become widely used.
-
- The documentation for JDK 1.2 explains that the Collection Framework
- defines three kinds of things:
- o Standard interfaces representing data structures of various kinds
- for you to implement. Since these are interfaces, you can use them
- in your code before you have implemented them.
- o Partial implementations of those interfaces, saving you some work.
- o Complete implementations, ready to use for data in your programs.
-
- The standard interfaces are Collection, Set, List and Map, plus the
- more specialised SortedSet and SortedMap. Lists have duplicate elements
- whereas Sets do not. Finer distinctions such as immutability are
- defined in the implementor classes, enforced by throwing runtime
- exceptions. See the JDK 1.2 documentation for a full discussion. Also
- see http://byrden.com/java/Tree/index.shtml for a description of
- extending the collection framework, and a freeware class implementing
- trees.
-
- For more about sorting prior to JDK 1.2, look at the class SortDemo in
- the demo directory of the JDK. Alternatively, use one of the several
- classic sorts available from Roedy Green. They are supplied free with
- heavily commented Java source code.
-
- See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary at
- http://mindprod.com/index.html.
-
- Also, try the Java Generic Library. This library (JGL) is freely
- downloadable from http://www.objectspace.com/
-
- Also Visual Engineering has JChart at: http://www.ve.com. No licensing
- fees.
-
- Visual Numerics has its Java Numeric Library available for download at
- http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They offer the JNL as
- a proposed standard library for numerical functions missing from Java.
-
- 2. (Sect. 20) Why doesn't somebody write a shell in Java? Then they could
- use it on all platforms!
-
- [*] Somebody has done just that. Look at http://www.jsh.net/
-
- 3. (Sect. 20) Are there any URLs for other libraries?
-
- [*] Indeed, there are. The Java3D Repository http://java3d.sdsc.edu/
-
- 4. (Sect. 20) Are there any URLs for regular expression handlers in Java?
-
- [*] There was one from ORO Inc, but they seem to have gone away. Their
- code, along with lots of other useful Java things is at
- http://web.theorem.com/java/index.htm
- For other sources, see
- http://Meurrens.ML.org/ip-Links/Java/regex/index.html
-
- And don't forget to check out Lava -- a set of Java classes designed to
- support programmers who develop console-mode applications and/or C
- programmers who are converting to Java. The first release of Lava has
- printf and other text formatting, encryption, parsing and miscellaneous
- I/O. Lava can be downloaded from http://www.newbie.net/sharky/lava/
-
- Also consider the Java version of the Unix find command. It offers
- Regex filename matching, mindepth, maxdepth, symlink follow / no
- follow, file type matching all cross-platform. The package is at
- http://www.geocities.com/~shecter/java.html
-
- 5. (Sect. 20) Are there any installers for Java? Preferably
- platform-neutral ones.
-
- [*] There are several possibilities.
- o InstallAnywhere 2 from ZeroG software. See
- http://www.zerog.com/html/installanywhere_2.html
- They have a free version for shareware authors.
- o InstallShield makes a Java version of their installation package.
- See http://www.installshield.com/java/default.asp
- o IBM offers a comprehensive Java installer through its alphaworks
- site http//www.alphaworks.ibm.com/formula/installtoolkit
-
- 6. (Sect. 20) What is "Jazilla"?
-
- [*] Jazilla is Mozilla (Netscape Communicator free source) ported to
- Java. In other words, a free source browser that supports Java and
- Javascript, written in Java!
-
- You can get more information, and volunteer to help with the project at
- http://www.jazilla.org/
-
- 7. (Sect. 20) Where can I get Java for my Palm Pilot PDA?
-
- [*] There is a translator allowing you to compile Java programs for the
- Palm Pilot PDA! This is an astonishing piece of work as the Pilot has
- such a small memory footprint. The translator is in an early stage of
- development, but is available at:
- http://www.cs.washington.edu/homes/mcdirmid/ghost
-
- Try it, or even better, volunteer to help with the project. Details at
- the website above.
-
- 8. (Sect. 20) What is "Dippy Bird" and where can I get it?
-
- [*] Dippy Bird is Java documentation in WinHelp format, which can be
- used directly on Windows desktops, and has a searching utility. The
- developer of the Dippybird project, Bill Bercik, has stopped further
- work on the project due to lack of time and funds. Instead you can use
- http://www.confluent.fr/javadoc/JavadocE.htm which has a more up to
- date Java WinHelp doc.
- You can get still get the Dippy Bird download at
- http://www.dippybird.com/jdk111.exe (JDK 1.1). Note that on NT 4.0 you
- need to change the generated shortcut to point to NT's 32-bit WinHelp.
-
- 9. (Sect. 20) Where can I get icons for use with Java?
-
- [*] Public spirited programmer and Java supporter Dean S. Jones has
- created a collection of over 100 icons for use in Java freeware. They
- are available on the Java Lobby site at
- http://webart.javalobby.org/jlicons/.
-
- 10. (Sect. 20) What the hell is "UML"?
-
- [*] UML is the Unified Modeling Language. It is unified in the sense
- that it draws together ideas from a couple of earlier software design
- languages. UML is an emerging standard for diagrams of object-oriented
- classes. It was devised by Grady Booch, Ivar Jacobsen, and James
- Rumbaugh, and it unifies several popular existing notations.
-
- UML is a product of Rational Software, who offer a tutorial CD for
- free. See http://www.rational.com/uml/tutorials2.html There are some
- whitepapers too, but there don't seem to be any free online tutorials.
-
- ObjectDesign Inc., has a UML designer written in 100% java. See
- http://www.objectdesign.com
-
- 11. (Sect. 20) Where can I get info on Java college courses?
-
- [*] The JCampus site at http://www.jcampus.org has links and
- connections to Java CS Dept. courses, assignments, academic papers and
- Java-related events. JCampus is a non-profit, online Community for CS
- Dept. professors, students and staff who are teaching, learning and
- using the Java programming language.
-
- 12. (Sect. 20) What is the Java IFAQ?
-
- [*] It is the Java list of Infrequently Answered Questions, a FAQ
- maintained by Peter Norvig, author of the book "Artificial Intelligence
- - A Modern Approach". Take a look at the Java IFAQ at
- http://www.norvig.com/java-iaq.html There's a lot of good information
- in that document.
-
- 13. (Sect. 20) Are there any Java tools for PDF?
-
- [*] PDF (Portable Document FOrmat) is the text publishing format
- defined by Adobe. Acrobat is the technology to display and print PDF
- files. Abode supplies the client (document reading) software for free.
- There is a PDF toolkit written in Java at http://www.etymon.com. Even
- better it is GPL'd. It is more a toolkit for programmers embedding PDF
- in their products, than an end-user technology though. It doesn't have
- a GUI for displaying PDF for example.
-
- 14. (Sect. 20) Are there any Java info search tools?
-
- [*] IBM has a very good search engine for java developers
- http://www.ibm.com/java
-
- 15. (Sect. 20) What other languages compile to bytecode?
-
- [*] Quite a lot of languages compile to Java bytecode, more than 60 at
- the last count. See the webpage
- http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html
-
- 16. (Sect. 20) Has anyone written a Java-to-RPC interface, to talk to
- legacy code?
-
- [*] See www.distinct.com. It implements a subset of RPC, and is a
- commercial, supported product. You can review RFCs 1831 and 1832 for
- information on the full protocol. Java uses the same endianness as
- RPC's external data representation (network byte order), so all the
- Java file reads/writes can be used directly.
-
- The specifications are in RFC 1831 (the RPC protocol spec) and RFP 1832
- (the XDR spec).
-
- 17. (Sect. 20) Are there any automated tools for Javadoc?
-
- [*] Yes. See http://www.mindspring.com/~chroma/docwiz/docwizApplet.html
- for a Java development tool called DocWiz. It is the easiest way to add
- JavaDoc comments to your Java code.
-
- -------------------------------
-
- 21. Acknowledgements
-
- A jolly little song that explains how to solve commonly-encountered problems
- in Java.
-
- The FAQ Melody
- by Antranig Basman.
-
- On the First Day of Christmas, my true-love said to me:
- Read the F-A-Q.
-
- On the Second Day of Christmas, my true-love said to me:
- My Image isn't drawing;
- Read the F-A-Q.
-
- On the Third Day of Christmas, my true-love said to me:
- My Pixels are not grabbing,
- My Image isn't drawing,
- Read the F-A-Q.
-
- On the Fourth Day of Christmas, my true-love said to me:
- My Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Fifth Day of Christmas, my true-love said to me:
- Null - Pointer - Exception!
- My Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Sixth Day of Christmas, my true-love said to me:
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Seventh Day of Christmas, my true-love said to me:
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Eighth Day of Christmas, my true-love said to me:
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Ninth Day of Christmas, my true-love said to me:
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Tenth Day of Christmas, my true-love said to me:
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Eleventh Day of Christmas, my true-love said to me:
- Docs are not specific,
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Pixels are not grabbing,
- Image isn't drawing,
- Read the F-A-Q.
-
- On the Twelfth Day of Christmas, my true-love said to me:
- File I/O's horrific,
- Docs are not specific,
- Time-zone's in Pacific,
- Dialogs-a-hanging,
- Threads they are a-blocking,
- J++ don't mind it,
- Netscape will not run it,
- Null - Pointer - Exception!
- Layout is not laying,
- Pixels are not grabbing,
- Image isn't drawing;
-
- You Should Read The-e F-A-Q!
-
- FAQ copyright 1997, 1998 by Peter van der Linden. Contributions and help
- from:
-
- Matt Kennel, Patric Jonsson, Brad Van Tighem, Tony Hursh, Glenn L
- Vanderburg, Peter Jones, John McDowall, Jim Driscoll, Uday, Dave Harris,
- Bill Wilkinson, Tom Valesky, Dan Drake, Giles Thomas, Mitch Baltuch, Guy
- Ruth Hammond, Gordon Keith, Jason Brome, Shani Kerr, Steve Chapel, Timothy
- Wolters, Robert Lynch, Jake Cormier, Sean C Sullivan, Joseph A. Millar, Jim
- Frost, Jim Balter, Jeff Bauer, John Kochmar, Carl Burke, William Stubbs,
- Mark Smith, Volker Turau, Real Gagnon, Russell Gold, Max Hailperin, Bill
- Tschumy, Marco Nijdam, Marc Pawlowsky, Laurence Vanhelsuwe,Ian Macgregor,
- Mike Faulkner, Rich Koch, Will Clark, Govind Seshadri, Rich Simkin, Ian
- Stiles, Kieren, Darren Christie, Tom Lane, Michael Jungmann, Rob Mayoff,
- George Ruban, Tom McCann, David Hopwood, Thomas Phan, Kai Stuke, Rolf
- Howarth, Derek Snider, David Boydston, Andy Godwin, John F. Dumas, Doug
- Bell, David J. Biesack, Tiger Quimpo, Martin Hugh Rogers, Brian Krahmer, Ian
- Burrell, Nikki Locke, Bin Li, Jackson Thompson, Steve Odendahl, Greg Smith,
- Jeffrey C. Ollie, Mark Halvin, Jeremy Cook, Lak Ming Lam, Peter S. Morris,
- Mark Halvin, Juergen Keil, Alex Stewart, Mike Abney, Rodney Stephenson, Mark
- Gritter, Satish Talim, Tamminen Eero, Alexander Gridnev, Eric Hodges, Jamey
- Graham, Will Lockhart, Scott Plante, Tom Sanfilippo, Jan Newmarch, Sean
- Breslin, Stuart D. Gathman, rhino@wwdc.com, C Matthew Curtin, Tor Iver
- Wilhelmsen, A.N.Pryke, Phil Race, David Holmes, David Rodal, Dominique
- Plante, Trent Jarvi, Ingrid Biery, Gopal Unni Krishnan, Grant Lewis, Tov Are
- Jacobsen, Gary McGath, Marty Hall, Will Forster, Colin Mummery, Darin
- McBride, Mayank Shah, Jens Alfke, Glen Stampoultzis, Philip Brown, Peter
- Steiner, Kurt Spaugh, Rasmus Ekman, Jonathan Revusky, Ken Kalish, Dave
- Sanders, Bill Hyden, James Cloughley, Philip "diodes" Gustafson, Paul
- Kinnucan, Juan Valdéz, Antranig Basman, Felix Pahl, David N. Still, Simon
- Arthur, Mark Hammond, Dan Kegel, Thomas Weidenfeller, Pavel Shvartsman,
- Christen Monberg, George Reese, Ian Macgregor, John Sublett, David
- Zimmerman, Tony Dahlman, Druid, Chris Kelly, Patricia Shanahan, Paul Hill,
- Lyne Lamoureux, Don Kennedy, Alec Muffett, Andrew Mickish, Pavel Shvartsman,
- Neil of Parkway Consultants, Chris Thiessen, David Michaels, Bob Sutherland,
- Michael Allen Latta, Joshy, Eric Albert, Wes Isberg, Lisa Retief, Michael
- Park, Dave Postill, Thomas Weidenfeller, Konstantin Laufer, Håkan
- Gustavsson, James Stauffer, Reuben Firmin, David Lim, Eamonn Maher, Craig
- West, Pavel Shvartsman, Jay Dunning, Kevin Swan, Grant Gainey, Dan Schmitt,
- Benjamin Goldberger, Jake Hamby, Yaakov Itzhaki, Robert Lynch
-
- ------------------------------------------------------------------------
-
- I am maintaining a FAQ list to address specifically programming issues
- (not a general tutorial on Java). Please mail suggested FAQ entries
- including answer to faqidea on the site afu.com.
- Question with answer gets you a credit in the FAQ.
- Peter van der Linden, Sun Certified Java Programmer.
- ------------------------------------------------------------------------
-
- Cross references
-
- Most cross reference links inside this document are still to be filled in
- after the great FAQ re-org. If you'd like to contribute a few, send me the
- new text for the NAME= and the HREF=, and I'll fold them in as time permits.
- Look at the FAQ source for the style to follow.
-
- Copyright
-
- Copyright (c), 1997,1998 Peter van der Linden. Permission to copy all or
- part of this work is granted for individual use, and for copies within a
- scholastic or academic setting. Copies may not be made or distributed for
- resale. The no warranty, and copyright notice must be retained verbatim and
- be displayed conspicuously. You need written authorization before you can
- include this FAQ in a book and/or a CDROM archive, and/or make a
- translation, and/or publish/mirror on a website (scholastic and academic use
- excepted). If anyone needs other permissions that aren't covered by the
- above, please contact the author.
-
- No Warranty
-
- This work is provided on an "as is" basis. The copyright holder makes no
- warranty whatsoever, either express or implied, regarding the work,
- including warranties with respect to merchantability or fitness for any
- purpose.
-
- ------------------------------------------------------------------------
-